状压DP
2016-07-24 21:36
218 查看
HDU1074,这题的大意是一个人需要完成他的作业,但是他的老师给他定了期限,每超过期限一天,就扣一分,问你如何安排做作业的顺序,才能使扣的分数最少,输出要扣的最小分数,并输出完成作业的顺序。(科目数目n<=15)
如果把n个科目进行排序,那么复杂度就有n!,肯定爆炸。其实每一个状态对于一种科目,只有两种可能,一是这个状态下做这个科目,二是不做这个科目,就是1,0两种状态,这样,我们就可以利用二进制很轻松的表示出来(比如101就是这个状态已经做了第一个科目和第三个科目)。利用二进制把状态用0,1表示,就是所谓的状态压缩,用这种方法,我们就可以在(2^n)*n的复杂度下解决这个问题,我们可以明显的看出,状态压缩一般也只能解决n<=20的问题,再大的话,时间也是不够的。
具体一点,就是用二进制的数表示当前的状态下的最优解。针对于这题,我们可以从一个状态,找到一个没有写的作业(就是为0的某一位),进行转移,最终(2^n - 1)这个状态就是最终完成所有作业的状态,它保存的答案也就是题目要求的最优解。
input:
2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3
output:
2
Computer
Math
English
3
Computer
English
Math
*/
如果把n个科目进行排序,那么复杂度就有n!,肯定爆炸。其实每一个状态对于一种科目,只有两种可能,一是这个状态下做这个科目,二是不做这个科目,就是1,0两种状态,这样,我们就可以利用二进制很轻松的表示出来(比如101就是这个状态已经做了第一个科目和第三个科目)。利用二进制把状态用0,1表示,就是所谓的状态压缩,用这种方法,我们就可以在(2^n)*n的复杂度下解决这个问题,我们可以明显的看出,状态压缩一般也只能解决n<=20的问题,再大的话,时间也是不够的。
具体一点,就是用二进制的数表示当前的状态下的最优解。针对于这题,我们可以从一个状态,找到一个没有写的作业(就是为0的某一位),进行转移,最终(2^n - 1)这个状态就是最终完成所有作业的状态,它保存的答案也就是题目要求的最优解。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = (1<<15) + 5; int dp[maxn]; int d[20],f[20];//数组d是期限,数组f是完成需要的时间 int pre[maxn],t[maxn];//数组pre是用来记录当前状态是由哪个状态推过来的,数组t是记录到当前状态用了多长时间 char a[20][110]; void output(int x) { if(!x) return; output(x-(1<<pre[x])); printf("%s\n",a[pre[x]]); } int main(void) { int T,n,m,i,j,inf = 1e9; scanf("%d",&T); while(T--) { scanf("%d",&n); for(i=0;i<n;i++) scanf("%s %d %d",a[i],&d[i],&f[i]); m = 1<<n; for(i=1;i<m;i++)//状态0表示一个科目都没完成,状态2^n-1表示全部科目都已完成 { dp[i] = inf; for(j=n-1;j>=0;j--) { int tem = 1<<j;//表示第j个科目 if((tem&i) == 0)//如果状态i还没有完成j,肯定不能由i-j推过来 continue; int s = t[i-tem] + f[j] - d[j];//表示扣的分数 if(s < 0)//扣的分数最小为0 s = 0; if(dp[i] > dp[i-tem] + s) { dp[i] = dp[i-tem] + s; t[i] = t[i-tem] + f[j]; pre[i] = j; } } } printf("%d\n",dp[m-1]); output(m - 1);//这里用了递归的方法进行输出 } return 0; }/*
input:
2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3
output:
2
Computer
Math
English
3
Computer
English
Math
*/
相关文章推荐
- bzoj1058无限TLE(人傻自带常熟大的splay)
- hihocoder 1139 二分答案+BFS求最短路
- 【ASP.NET】——Web服务器控件、HTML服务器控件
- 萌新的Canvas笔记(一)
- Java学习笔记之反射(Reflection)
- PAT A1046 Shortest Distance (20)
- AIDL
- MyEclipse Database Explorer配置浅析
- androidapp 检测到移动物体,通过web在电脑上实时显示出来
- 在mysql中关于通过多字段去除重复记录的方法
- Spring的注解驱动控制程序
- 测试
- linux服务之tuned
- CTF Field Guide
- git
- 使用Xcode Instruments Leak解决内存泄漏问题
- 【数据库】数据库设计
- HTML——图形标签
- 用俗话讲讲卡尔曼滤波与粒子滤波
- BitmapFactory解析与Bitmap的内存优化