若干人左对齐站成最多5行,给定每行站多少个,列数从第一排开始往后递减。要求身高从每排从左到右递增(我将题意篡改了便于理解233),每列从前向后递增。每个人身高为1...n(n<=30)中的一个数(互不不同)。求可行方案数。(地址点我qwq);


做了lyd书dp这一章的第一题,就不会qwq。。果然菜的人还是永远菜啊,注定翻不了身。

lyd的书上讲到了dp的方法,不是很理解。后来想通了,发现自己想的时候也想到了这一点转化,但是又很快把他抛弃掉了。。冏。

上面所谓的转化就是说,我本来安排人去排列,是无序的,显然也不好dp,因为高度不定,选了哪些也不知道,对后续状态有影响,所以要转化为有序的dp。有没有觉得很熟悉?BZOJ1079[SCOI2008]着色方案[组合计数DP]这里就是将无序的排列改为有序的插入。

对于要求从前面的一些状态中有条件限制的转移,当条件不易表达时,尝试将无序选择转化为有序的顺次选择简化之。

为什么顺序插入身高是对的?假设我已经插入$i$个身高最矮的人,那么身高$i+1$的人除了插入每一行的末尾别无选择,试想如果插在排好的队中,显然不单调。和末尾空了一格或多格站,那么中间就找不到合适身高的人站进去了。当然也要保证插入的行的当前人数少于上一行的,不然上一行会比这一行少空位,之后身高更高的人也没办法站上去。这样做完,就可以保证排列方案满足要求。有没有什么方案不能通过上面这种方案构造出来的?没有,因为不按上面那种插入的话,其他情况必然无解。所以对于每一种可行方案,我可以认为他是按从小到大身高顺序每个依次在某一行末尾插入的得到的。那么我就可以顺理成章设f[a][b][c][d][e]来记录状态了,然后就是lyd书上的做法。对于每个状态,去推出其他可以拓展的后续状态(在这题也就是再插入身高排名下一位的人)。

实现上dp数组开满会爆内存,可以采用动态开数组(说白了就是主函数内部根据大小开数组),或者f[31][16][11][8][7]也可以,为什么您们都看得出来。。然而前者速度吊打后者,因为是动态开的嘛,后者每次还要全部清空。

其他一些细节(比如不满5行怎么办)看code,也可以照例解决,就把空的几行看成数组下标是0即可。

另:勾长公式挂在标题上是摆设。。我不太想学,因为有点冷门,而且应当不会考这玩意儿的说。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define ddbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;int p=;char c;while(!isdigit(c=getchar()))if(c=='-')p=;
while(isdigit(c))x=x*+(c&),c=getchar();return p?x=-x:x;
}
int x[];
int n;
int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
while(read(n),n){
memset(x,,sizeof x);
for(register int i=;i<=n;++i)read(x[i]);
unsigned int f[x[]+][x[]+][x[]+][x[]+][x[]+];
memset(f,,sizeof f);
f[][][][][]=;
for(register int a=;a<=x[];++a)
for(register int b=;b<=x[];++b)
for(register int c=;c<=x[];++c)
for(register int d=;d<=x[];++d)
for(register int e=;e<=x[];++e){
f[a+][b][c][d][e]+=f[a][b][c][d][e];
if(b<a)f[a][b+][c][d][e]+=f[a][b][c][d][e];
if(c<b)f[a][b][c+][d][e]+=f[a][b][c][d][e];
if(d<c)f[a][b][c][d+][e]+=f[a][b][c][d][e];
if(e<d)f[a][b][c][d][e+]+=f[a][b][c][d][e];
}
printf("%u\n",f[x[]][x[]][x[]][x[]][x[]]);
}
return ;
}

poj2279 Mr. Young's Picture Permutations[勾长公式 or 线性DP]的更多相关文章

  1. POJ2279 Mr Young's Picture Permutations

    POJ2279 Mr Young's Picture Permutations 描述: 有N个学生合影,站成左对齐的k排,每行分别有N1,N2…NK个人,第一排站最后,第k排站之前.学生身高依次是1… ...

  2. 【题解】POJ2279 Mr.Young′s Picture Permutations dp

    [题解]POJ2279 Mr.Young′s Picture Permutations dp 钦定从小往大放,然后直接dp. \(dp(t1,t2,t3,t4,t5)\)代表每一行多少人,判断边界就能 ...

  3. poj2279——Mr. Young's Picture Permutations

    Description Mr. Young wishes to take a picture of his class. The students will stand in rows with ea ...

  4. 轮廓线DP:poj 2279 Mr. Young's Picture Permutations

    poj 2279 Mr. Young's Picture Permutations \(solution:\) 首先摘取一些关键词:(每行不超过它后面的行)(每排学生安排高度从左到右减少)(学生的高度 ...

  5. bzoj 2483: Pku2279 Mr. Young's Picture Permutations -- 钩子公式

    2483: Pku2279 Mr. Young's Picture Permutations Time Limit: 1 Sec  Memory Limit: 128 MB Description   ...

  6. Mr. Young's Picture Permutations

    Mr. Young's Picture Permutations 给出一个有k列的网格图,以及每列图形的高度\(n_i\),下端对齐,保证高度递减,设有n个网格,询问向其中填1~n保证每行每列单调递增 ...

  7. 【杨氏矩阵+勾长公式】POJ 2279 Mr. Young's Picture Permutations

    Description Mr. Young wishes to take a picture of his class. The students will stand in rows with ea ...

  8. [POJ 2279] Mr. Young's Picture Permutations

    [题目链接] http://poj.org/problem?id=2279 [算法] 杨氏矩阵与勾长公式 [代码] #include <algorithm> #include <bi ...

  9. POJ P2279 Mr. Young's Picture Permutations 题解

    每日一题 day14 打卡 Analysis 五维dpf[a1,a2,a3,a4,a5]表示各排从左端起分别占了a1,a2,a3,a4,a5个人时合影方案数量然后我们枚举a1,a2,a3,a4,a5从 ...

随机推荐

  1. springboot和springcloud版本冲突问题

    最近搭建eureka项目,出现boot和cloud版本不匹配错误,记录下来 2019-12-06 14:00:20.043 ERROR 180780 --- [ main] o.s.boot.Spri ...

  2. ASP.NET Session详解(转)

    ASP.NET Session详解 本文章来自:http://blog.163.com/adam601@126/blog/static/22506317200932824210996/ 当用户在 We ...

  3. java内存模型的实现

    前几天,发了一篇文章,介绍了一下JVM内存结构.Java内存模型以及Java对象模型之间的区别.其中,Java内存模型,是这三个知识点当中最晦涩难懂的一个,而且涉及到很多背景知识和相关知识. 网上有很 ...

  4. JS中FireFox新开窗口预览打印处理的方式

    仅提供思路,勿喷如下↓ /** * 打印方法 * @param dom 要被打印的dom元素 * @param parentClassName 该组件的页面根组件class名 * @param pag ...

  5. 递归拷贝目录与删除目录 WindowsAPI C++

    /*判断一个路径是否是已存在的目录*/ bool IsDirectory(const std::wstring& pstrPath) { DWORD dw = GetFileAttribute ...

  6. Windows系统中CMD wmic查看硬盘、内存、CPU、BIOS、网卡等信息。(附带脚本)

    目录 Windows系统中CMD wmic查看硬盘.内存.CPU.BIOS.网卡等信息. 查看内存相关 查看内存主板数量(两条命令均可) 查看物理内存 查看逻辑内存 查看缓存 查看虚拟内存 查看网络相 ...

  7. 【Python】【基础知识】【内置函数】【dir的使用方法】

    原英文帮助文档: dir([object]) Without arguments, return the list of names in the current local scope. With ...

  8. python装饰器的原理

    装饰器的原理就是利用<闭包函数>来实现,闭包函数的原理就是包含内层函数的return和外层环境变量:

  9. Java中的异常处理try catch(第八周课堂示例总结)

    异常处理 使用Java异常处理机制: 把可能会发生错误的代码放进try语句块中. 当程序检测到出现了一个错误时会抛出一个异常对象. 异常处理代码会捕获并处理这个错误. catch语句块中的代码用于处理 ...

  10. std::tr1::function和bind组件

    C++中std::tr1::function和bind 组件的使用 在C++的TR1中(Technology Report)中包含一个function模板类和bind模板函数,使用它们可以实现类似函数 ...