hdoj1074 Doing Homework (状态压缩 DP)
来源:互联网 发布:未来软件家园 编辑:程序博客网 时间:2024/05/30 04:51
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1074
题意:
老师们布置了n(1<=n<=15)门课程的作业,每门作业老师规定了各自的完成期限为xi天(记为deadline),而学生实际完成一门需要yi天(记为finish);各科作业如果学生晚交t天会被该科老师扣t分平时表现成绩,学生如何安排作业才能使平时分扣得最少?各科课程名按字典序输入,每科后面跟着deadline和finish时间,要求输出最少扣分,以及各科作业安排顺序,有多种情况就只输出字典序最小的情况。
思路:
先讨论最多有n (n=15)门课程的情况,第一反应是这n门课程需要做全排列,有n!种情况,时间复杂度太高行不通;试着考虑先组合,再利用动态规划来优化排列。
用二进制000000000000000~111111111111111这2^n种状态status表示这n门课程取舍的组合状态(0<=status<2^n),status的二进制位为1表示已经完成该位置的作业,为0表示未完成。
dp[status]=min{dp[status^(1<<j)]+max(last[status^(1<<j)]+finish[j]-deadline[j], 0), dp[status]},这里0<=j<n,status^(1<<j)表示把status这个状态下的第j个作业标记为未完成,也就是最后完成j作业的前状态,max(last[status^(1<<j)]+finish[j]-deadline[j], 0)表示最后完成j作业贡献的分数,last[status^(1<<j)]表示前状态组合完成作业所花的总时间,这里0<=j<n是在枚举同一status组合状态下所有可以被安排在最后完成作业的情况,这些情况中dp[status]值最小的保留,并记录该状态下最后完成的作业j值。
当dp[status]有多种情况值相等时,保留字典序较大的j值,因为字典序较大的是最后完成的,满足题意字典序较小放前面;又由于题目中已经说明按字典序输入课程名,因此这里当出现dp[status]等值时,在后面被枚举的状态一定是字典序较大的,可以直接存j值。
#include <stdio.h>#include <string.h>int ans[1<<15];char sub[15][101];int max(int a,int b){return a>b?a:b;}int solve(int s){if(s==0)return 0;solve(s ^ (1<<ans[s]));printf("%s\n",sub[ans[s]]);}int main(){int i,j,n;int cas,deadline[15],finish[15];int dp[1<<15],last[1<<15];int status;int MAXN=1000000000;scanf("%d",&cas);while(cas--){scanf("%d",&n);status=1<<n;for(i=0;i<n;i++)scanf("%s %d %d",sub[i],&deadline[i],&finish[i]);for(i=0;i<status;i++){last[i]=0;for(j=0;j<n;j++){if(i & (1<<j)){last[i]+=finish[j];}}}dp[0]=0;for(i=1;i<status;i++){dp[i]=MAXN;for(j=0;j<n;j++){if(i & (1<<j)){if(dp[i^(1<<j)] + max(0, last[i^(1<<j)] + finish[j] - deadline[j]) <= dp[i]){dp[i]=dp[i^(1<<j)] + max(0, last[i^(1<<j)] + finish[j] - deadline[j]);ans[i]=j;}}}}printf("%d\n",dp[status-1]);solve(status-1);}return 0;}
- hdoj1074 Doing Homework (状态压缩 DP)
- hdoj1074 Doing Homework(好题呀,状态压缩+DP)
- hdu1074 Doing Homework(状态压缩dp)
- hdu1074 Doing Homework (状态压缩dp)
- hdu 1074 Doing Homework(dp+状态压缩)
- HDU 1074 Doing Homework (状态压缩DP)
- hdu 1074 Doing Homework (状态压缩 + DP)
- HDU1074 Doing Homework 状态压缩DP
- HDOJ 1074 Doing Homework (状态压缩DP)
- HDU1074: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
- hdoj 1074 Doing Homework 【状态压缩dp】
- hdu 1074 Doing Homework 状态压缩dp
- 故障案例--mongo 3.0鉴权导致cpu居高不下
- nyoj 487点数(向量积判断三角形内部的整点)
- 如何查看codeblock的头文件
- HTML基础[思维导图]
- [线段树 点更新 段查询]A
- hdoj1074 Doing Homework (状态压缩 DP)
- 互信息(Mutual Information)和χ 2特征选择方法去噪处理
- laravel学习
- 权限修饰符、状态修饰符、抽象修饰符使用规则
- 常用ADB命令使用和adb logcat 命令行用法 monkey压力测试
- Android 自定义弹窗
- 教你彻底解决Eclipse自动补全变量
- bzoj1417: Pku3156 Interconnect
- Java中一次对象的自我拯救探究