hdu 1074 Doing Homework (状态压缩dp)
来源:互联网 发布:招聘游戏程序员 编辑:程序博客网 时间:2024/05/22 00:06
题目大意:需要交n个作业,每个作业都有一个截止时间和做这个作业所需要花费的时间。如果上交作业的时间大于截止时间,则要被扣分,超出截止日期多长时间则会被扣多少分,让你求被扣的最小的分数,并输出字典序最小的方案。
状态压缩dp,用二进制表示状态,1代表这门课的作业已经做完,0代表没做,定义dp[i][j]为做完i个作业时所扣的最小分数,j表示做了哪几门作业。
状态转移方程为 dp[i][当前做了哪些作业] = min { dp[i-1][做了i-1个作业的时候做了哪些作业] + 扣的分数 }
输出字典序最小的方案,我是用的一个字符串来保存每次写了哪个作业,比如如果做作业的顺序是Computer->Math->English,那么这个字符串就是"132",因为第一次做了Computer的作业,Computer的字典序最小,所以第一位为1,第二次做了Math,Math的字典序最大,所以第二位为3,第三次做了English,所以第三位为2.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int dp[20][(1<<15)+5];int dead[20],c[20],n;char order[20][(1<<15)+5][20];char str[20][105];int f(int k){ int ct=0; int i=0; while(k>>i) { if( (k>>i) & 1 ) ct++; i++; } return ct;}int day(int k){ int i=0,ans=0; while(k>>i) { if( (k>>i) & 1 ) ans+=c[n-i]; i++; } return ans;}int main(){ int t; scanf("%d",&t); while(t--) { memset(dp,127,sizeof(dp)); memset(order,0,sizeof(order)); const int INF=dp[0][0]; int i,j,k; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%s%d%d",str[i],&dead[i],&c[i]); for(j=0;j<(1<<n);j++) dp[0][j]=0; for(i=1;i<=n;i++) { for(j=0;j<(1<<n);j++)//枚举做了i-1个作业时的状态 { for(k=1;k<=n;k++)//枚举做的第i个作业是哪个 { if( f(j)==i-1 && ( (1<<(n-k)) & j )==0 )//如果做的第i个作业与之前的作业不重复 { int tmp=c[k]+ day(j) -dead[k];//tmp为扣的分数 if(dp[i][ (1<<(n-k)) | j ] > dp[i-1][j]+ ( tmp < 0 ? 0 : tmp )) { dp[i][ (1<<(n-k)) | j ] = dp[i-1][j]+ ( tmp < 0 ? 0 : tmp ); char stmp[20]={0}; strcpy(stmp,order[i-1][j]); stmp[strlen(stmp)]=k; strcpy(order[i][ (1<<(n-k)) | j ],stmp); } else if(dp[i][ (1<<(n-k)) | j ] == dp[i-1][j]+ ( tmp < 0 ? 0 : tmp )) { char stmp[20]={0}; strcpy(stmp,order[i-1][j]); stmp[strlen(stmp)]=k; if( strcmp(order[i][ (1<<(n-k)) | j ],stmp)>0 ) strcpy(order[i][ (1<<(n-k)) | j ],stmp); } } } } } int ans=INF-1; char ans_order[20]; for(j=0;j<(1<<n);j++) { if(dp[n][j]<ans) { ans=dp[n][j]; strcpy(ans_order,order[n][j]); } else if(dp[n][j]==ans) { if(strcmp(ans_order,order[n][j])>0) strcpy(ans_order,order[n][j]); } } printf("%d\n",ans); int len=strlen(ans_order); for(i=0;i<len;i++) { printf("%s\n",str[(int)ans_order[i]]); } } return 0;}
0 0
- hdu 1074 Doing Homework(dp+状态压缩)
- HDU 1074 Doing Homework (状态压缩DP)
- hdu 1074 Doing Homework (状态压缩 + DP)
- HDU-1074 Doing Homework 状态压缩DP
- HDU 1074 Doing Homework(状态压缩DP)
- hdu 1074 Doing Homework(状态压缩dp)
- hdu 1074 Doing Homework dp+状态压缩
- hdu 1074 状态压缩+DP Doing Homework
- HDU 1074 Doing Homework 状态压缩DP
- hdu 1074 Doing Homework 状态压缩dp
- Hdu 1074 Doing Homework 状态压缩DP
- 状态压缩DP-HDU-1074-Doing Homework
- HDU 1074 Doing Homework DP 状态压缩
- hdu 1074 Doing Homework 状态压缩dp
- HDU 1074 Doing Homework(状态压缩dp)
- hdu 1074 doing homework(状态压缩dp)
- hdu 1074 Doing Homework 状态压缩DP
- HDU 1074 Doing Homework【状态压缩DP】
- Android中的GridView详解
- hdu4635 有向图最多添加多少边使图仍非强连通
- Css-TH,TR,TD
- C#调用ORCLe 带参数select存储过程--10g及以下
- Qt实现3D纹理渲染自由旋转空间立方体
- hdu 1074 Doing Homework (状态压缩dp)
- 冒泡排序实现--python
- Fibnacci序列 1
- Spinner
- codeforces#259 div2 (a,b,c)三题
- The 36th ACM/ICPC Asia Regional Dalian Site —— Online Contest(套题HDU4001-4010)
- Fibnacci序列2
- 程序员笑话
- 暑期实训第四课(无线串口模块进行通讯)