最小美观程度
2015-08-29 00:06
246 查看
题目描述
某公司运进一批箱子,总数为N(1≤N≤1000)由“传送带”依次运入,然后在仓库内至多排成P(1≤P≤4)列,(如图8所示)。
现已知运来的箱子最多为M(1≤M≤20)种,想把同一种类的箱子尽量排在一起,以便美观。“美观程度”T定义为:T=∑\sum(每列依次看到的不同种类数);所谓“依次看到的不同种类数”即为:如果某一列中第K个箱子与第K-1个箱子种类不同,则“美观程度”的值加1。求一种调动安排,使各列的“美观程度”值的和最小。(只输出最小值)
中国好样例
输入:
30 10 4
1 1 8 2 3 7 3 2 4 4 1 5 1 8 1 3 9 4 7 3 7 8 7 3 2 3 5 3 8 3
输出:
12
最优子结构很明显,动龟(动态规划)!初始想法:用f[i]f[i]表示前ii个箱子所能获得的最小美观程度,分析后发现无法写出状态转移方程(这是有后效性的节奏啊)……再次分析可以得出:把当前箱子不论放在哪一列仅与当前栈顶(第一个)元素有关,所以用f[i][a1][a2][a3][a4]f[i][a1][a2][a3][a4](PP最大为44)来表示前ii个箱子,当栈顶元素分别为a1、a2、a3、a4a1、a2、a3、a4时的最小美观程度,用前面的结果去更新后面的结果,貌似可以,终于没有后效性了,但仔细一想,卧槽,时间和空间复杂度……再来,很明显,栈顶元素分别为4、6、8、24、6、8、2其实与8、4、2、68、4、2、6是一样的(列与列之间没有差别),这样就可以把全排列优化为1种情况,一个很不错的进步,但是编程复杂度的问题……再来,撞鸭(状态压缩)!由于a1、a2、a3、a4a1、a2、a3、a4最大是MM,显然我们可以用一个M+1M+1进制的数字xx来同时记录a1、a2、a3、a4a1、a2、a3、a4,最大约为10510^5级别的,加上第一维的NN了以后貌似还不够明显……再来,再一分析可以发现,f[i]f[i]只与f[i−1]f[i-1]有关,这是用滚动数组的节奏啊。
OK,到这里,时间和空间就都能承受了,我也已经无力再去优化了。
(注:我码力太弱,上TA大神的代码)
某公司运进一批箱子,总数为N(1≤N≤1000)由“传送带”依次运入,然后在仓库内至多排成P(1≤P≤4)列,(如图8所示)。
现已知运来的箱子最多为M(1≤M≤20)种,想把同一种类的箱子尽量排在一起,以便美观。“美观程度”T定义为:T=∑\sum(每列依次看到的不同种类数);所谓“依次看到的不同种类数”即为:如果某一列中第K个箱子与第K-1个箱子种类不同,则“美观程度”的值加1。求一种调动安排,使各列的“美观程度”值的和最小。(只输出最小值)
中国好样例
输入:
30 10 4
1 1 8 2 3 7 3 2 4 4 1 5 1 8 1 3 9 4 7 3 7 8 7 3 2 3 5 3 8 3
输出:
12
最优子结构很明显,动龟(动态规划)!初始想法:用f[i]f[i]表示前ii个箱子所能获得的最小美观程度,分析后发现无法写出状态转移方程(这是有后效性的节奏啊)……再次分析可以得出:把当前箱子不论放在哪一列仅与当前栈顶(第一个)元素有关,所以用f[i][a1][a2][a3][a4]f[i][a1][a2][a3][a4](PP最大为44)来表示前ii个箱子,当栈顶元素分别为a1、a2、a3、a4a1、a2、a3、a4时的最小美观程度,用前面的结果去更新后面的结果,貌似可以,终于没有后效性了,但仔细一想,卧槽,时间和空间复杂度……再来,很明显,栈顶元素分别为4、6、8、24、6、8、2其实与8、4、2、68、4、2、6是一样的(列与列之间没有差别),这样就可以把全排列优化为1种情况,一个很不错的进步,但是编程复杂度的问题……再来,撞鸭(状态压缩)!由于a1、a2、a3、a4a1、a2、a3、a4最大是MM,显然我们可以用一个M+1M+1进制的数字xx来同时记录a1、a2、a3、a4a1、a2、a3、a4,最大约为10510^5级别的,加上第一维的NN了以后貌似还不够明显……再来,再一分析可以发现,f[i]f[i]只与f[i−1]f[i-1]有关,这是用滚动数组的节奏啊。
OK,到这里,时间和空间就都能承受了,我也已经无力再去优化了。
(注:我码力太弱,上TA大神的代码)
[code]#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define S 21 int f[2][194485],p,now,pre=1,mi[5],m,a; void dfs(int x,int state){ if(x<0){ if(f[pre][state]<1000){ int i; for(i=p;i--;){ x=state%mi[i+1]/mi[i]; //取第i个栈顶元素 f[now][state+(a-x)*mi[i]]=min(f[now][state+(a-x)*mi[i]],f[pre][state]+(x!=a)); //状态转移 } } return; } for(int i=m;~i;--i)dfs(x-1,state*(m+1)+i); } int main(){ int n,i; scanf("%d%d%d",&n,&m,&p); mi[0]=1; for(i=1;i<5;++i)mi[i]=mi[i-1]*(m+1);//幂 memset(f,127,sizeof(f)); f[0][0]=0; while(n--){ scanf("%d",&a); swap(now,pre);//滚动数组 memset(f[now],127,sizeof(f[now])); dfs(p,0); } printf("%d\n",*min_element(f[now],f[now+1])); //取容器中最小值 }
相关文章推荐
- REST构架风格介绍:状态表述转移
- 什么是REST?以及RESTful的实现
- 网络知识点大杂烩
- 条款5:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls)
- Objective-C 【完整OC项目-购票系统-系统分析-代码实现】
- 使用 XML 实现 REST 式的 SOA
- Objective-C 【完整OC项目-购票系统-系统分析-代码实现】
- LVS类型详解及其调度方法
- ios开发-电话本的设计与实现
- 本地编译 全志a33 的步骤
- 编程经验:Cmake编译Opencv3.0&extra model所遇到的种种问题~
- Comet:基于 HTTP 长连接的“服务器推”技术
- usaco Prime Palindromes
- Adapter的使用步骤和baseAdapter的使用以及inflater的一些运用
- ios开发-UI-自定义Tabbar 图书布局
- Fragment与Activiy之间的交互
- ubuntu12.04下安装Docker
- 详解Java二叉排序树
- Asp.net下拉树的实现过程
- 12306动态验证码启发之ASP.NET实现动态GIF验证码(附源码)