hdu 1074 Doing Homework(状态压缩dp)
2016-03-21 21:33
471 查看
Doing Homework
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1074解题思路:
题目大意:有n门课程作业,每门作业的截止时间为D,需要花费的时间为C,若作业不能按时完成,每超期1天扣1分。这n门作业按课程的字典
序先后输入。
问完成这n门作业至少要扣多少分,并输出扣分最少的做作业顺序。
PS:达到扣分最少的方案有多种,请输出字典序最小的那一组方案。
算法思想:
因为最多只有15门课程,可以使用二进制来表示所有完成的状况。
例如5,二进制位101,代表第一门和第三门完成了,第二门没有完成,那么我们可以枚举1~1<<n便可以得出所有的状态。
然后对于每一门而言,其状态是t = 1<<i,我们看这门在现在的状态s下是不是完成,可以通过判断s&t是否为1来得到。
当得出t属于s状态的时候,我们便可以进行dp了,在dp的时候要记录路径,方便之后的输出。
AC代码:
#include <bits/stdc++.h>using namespace std;
const int INF = 0x3f3f3f3f;
struct Course{
string name;
int deadline,cost;
}course[50];
struct node{
int score,now,pre,time;
}dp[1<<15];
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i = 0; i < n; i++)
cin >> course[i].name >> course[i].deadline >> course[i].cost;
int sum = 1<<n;
for(int i = 1; i < sum; i++){
dp[i].score = INF;
for(int j = n-1; j >= 0; j--){
int tmp = 1<<j;
if(i & tmp){
int past = i-tmp;
int st = dp[past].time+course[j].cost-course[j].deadline;
if(st < 0)
st = 0;
if(st+dp[past].score < dp[i].score){
dp[i].score = st+dp[past].score;
dp[i].now = j;
dp[i].pre = past;
dp[i].time = dp[past].time+course[j].cost;
}
}
}
}
stack<int> s;
int tmp = sum-1;
cout << dp[tmp].score << endl;
while(tmp){
s.push(dp[tmp].now);
tmp = dp[tmp].pre;
}
while(!s.empty()){
cout << course[s.top()].name << endl;
s.pop();
}
}
return 0;
}
相关文章推荐
- 递归与尾递归(C语言)
- 全选,反选,不选 小代码
- Alluxio之定位策略
- 一天一个小算法--排序之冒泡
- asp Session 串号的解决方法
- day19——数据迁移——exp,imp
- day19——数据迁移
- day18——sql优化——绑定变量
- day18——sql优化
- day18——索引
- Python之logging模块
- Qemu&KVM第二篇之(3)使用virsh xml file 创建VM
- 在ubuntu中为chromium安装crx插件--以adblock为例
- iOS开发网络篇—NSURLConnection基本使用
- MySQL系列:单表&多表数据查询
- Win7下 python安装Scrapy
- Android硬件监听
- FFT与多项式、生成函数题目泛做
- tcp粘包,udp丢包
- apue- chapter 3 文件IO