HDU 1074 Doing Homework (dp+状态压缩)
2013-08-24 03:47
274 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074
题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一天则扣掉一单位学分, 要你求出完成所有作业而被扣最小的学分, 并将完成作业的顺序输出.
[align=left]Sample Input[/align]
2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3
[align=left]Sample Output[/align]
2
Computer
Math
English
3
Computer
English
Math
分析:(转)
刚开始以为是背包, 但背包难以记录输出顺序, 所以只能换另一种DP方式, 这里科目最大数目才15, 只要有全枚举的思想来DP就可以解决了, 有一个专有名词叫状态压缩DP. 状态压缩DP采用二制进的思想,
1, 0分别代表有或否.
如:
3的二进制为 11, 则代表完成了每一,二个科目的状态, 101代表完成了第一三两个科目的状态.
这样, 可以从0->(1 << N)来获取所有状态, 并进行适当的状态转移. 对该题来说 D[s]代表集合s的状态, 要得到D[s]的状态, 可以从0 - N 分别检查是否在s集合内[s & (1 << i) > 0则表示i在集合s上,反之..], 如果i在s集合内, 刚D[s]可从D[s-{i}]来获得, [s-{i},可以s - (1<<i)来计算]. 这样表示在已完成了s-{i}的基础上再完成i后的装态, 遍历i, 取最优解.
代码如下:
题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一天则扣掉一单位学分, 要你求出完成所有作业而被扣最小的学分, 并将完成作业的顺序输出.
[align=left]Sample Input[/align]
2
3
Computer 3 3
English 20 1
Math 3 2
3
Computer 3 3
English 6 3
Math 6 3
[align=left]Sample Output[/align]
2
Computer
Math
English
3
Computer
English
Math
分析:(转)
刚开始以为是背包, 但背包难以记录输出顺序, 所以只能换另一种DP方式, 这里科目最大数目才15, 只要有全枚举的思想来DP就可以解决了, 有一个专有名词叫状态压缩DP. 状态压缩DP采用二制进的思想,
1, 0分别代表有或否.
如:
3的二进制为 11, 则代表完成了每一,二个科目的状态, 101代表完成了第一三两个科目的状态.
这样, 可以从0->(1 << N)来获取所有状态, 并进行适当的状态转移. 对该题来说 D[s]代表集合s的状态, 要得到D[s]的状态, 可以从0 - N 分别检查是否在s集合内[s & (1 << i) > 0则表示i在集合s上,反之..], 如果i在s集合内, 刚D[s]可从D[s-{i}]来获得, [s-{i},可以s - (1<<i)来计算]. 这样表示在已完成了s-{i}的基础上再完成i后的装态, 遍历i, 取最优解.
代码如下:
# include<iostream> # include<cstdio> # include<string> # include<cstring> # include<stack> using namespace std; const int MAXN = 16; const int INF = 0xffffff; struct Homework{ string name; int deadline; //截止时间 int time; //完成时间 }data[MAXN]; struct { int time; //完成该集合作业所需时间 int score; //完成该集合作业被扣学分 int last; //记录上一个位置 int pos; //记录当前位置 }dp[1<<MAXN]; int main(){ int T,n; int i; cin>>T; while(T--){ cin>>n; for(i=0;i<n;i++) cin>>data[i].name>>data[i].deadline>>data[i].time; int endstate = 1<<n; int recent = 0; int reduce = 0; int past = 0; for(int S=1; S<endstate; S++){ dp[S].score = INF; for(i=n-1;i>=0;i--){ recent = 1<<i; if(S & recent){ past = S - recent; //余下的作业集合 reduce = dp[past].time + data[i].time - data[i].deadline; //完成该作业被扣学分,小于0则不扣 if(reduce < 0) reduce = 0; if(reduce + dp[past].score < dp[S].score){ dp[S].time = dp[past].time + data[i].time; dp[S].score = reduce + dp[past].score; dp[S].pos = i; dp[S].last = past; } } } } stack<int >path; //保存路径 recent = endstate - 1; //1<<n-1,表示n个1的2进制数,即全集 while(recent){ path.push(dp[recent].pos); recent = dp[recent].last; } cout << dp[endstate-1].score<<endl; while(!path.empty()){ int top = path.top(); cout<<data[top].name<<endl; path.pop(); } } return 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)
- HDU1074 Doing Homework 状态压缩dp
- hdu1074 Doing Homework (状态压缩dp)
- HDU 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)
- HDU1074 Doing Homework 状态压缩dp
- Hdu 1074 Doing Homework 状态压缩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)