HDU 1074(状态压缩dp)
2015-11-28 16:47
369 查看
//起初想到贪心没思路 看了题解 状态压缩DP 最多15个状态 // [1, 1<<n) 枚举各个状态推出的每种可能即可 //注意题意说如果答案相同输出字典序最优的答案 //只需要在枚举的时候处理下就好 这里理解了好一会儿 #include <iostream> #include "stdio.h" #include "stdlib.h" #include "string.h" #include "algorithm" #include <queue> #include <stack> #define N (1 << 15) + 5 #define INF 1<<30 using namespace std; int dp , Time , pre , n, ans; //dp 存放到达各个状态最少的扣分数,Time 存放到达各个状态扣分最少所需的时间,pre 各个状态的前驱 stack<int> sta; struct node{ int deadline, cost; char name[105]; } subjuct[20]; //各个科目的作业 int main() { int t; //freopen("t", "r", stdin); scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%s%d%d", subjuct[i].name, &subjuct[i].deadline, &subjuct[i].cost); ans = 1 << n; for(int i = 1; i < ans; i++){ dp[i] = INF; for(int j = n; j >= 1; j--){ //这里是重点 为了保证输出的答案满足字典序最优 这里是j从最后一个作业往前枚举 int tmp = 1 << (j-1); //因为一旦j枚举成功 就相当于作业j放在最后完成 if(tmp & i) { int last = i - tmp; //第j个作业没做的之前的状态 int cost = max(Time[last] + subjuct[j].cost - subjuct[j].deadline, 0); //计算做了第J个作业增加的扣分数 if(dp[i] > dp[last] + cost) //如果扣分数小于之前的方案就更新 { dp[i] = dp[last] + cost; pre[i] = j; //更新前驱 Time[i] = Time[last] + subjuct[j].cost; //更新到达状态i的时间值 } } } } printf("%d\n", dp[ans - 1]); int tmp = ans - 1; while(tmp) //找前驱并入栈 { sta.push( pre[tmp] ); tmp -= 1 << (pre[tmp] - 1); } while(!sta.empty()) //输出结果 { printf("%s\n", subjuct[sta.top()].name); sta.pop(); } } return 0; }
相关文章推荐
- The Falling Leaves(建树方法)
- nginx 源码学习笔记(二)——nginx精粹-模块
- WebHDFS REST API
- TEXT到EPUB格式转换
- 项目总结:以网络安全为例的大数据可视化设计
- 高精度模板
- 1-4-02:输出绝对值
- Document Filtering(naive bayes method) used by python
- 百度地图API示例之添加定位相关控件
- Safecracker
- nginx 源码学习笔记(一)——初识nginx helloworld模块
- 案例:弹幕表白技术
- 手电筒之指南针
- 博客散乱说
- C API libhdfs
- yacc的运行参数
- iOS流布局UICollectionView系列一——初识与简单使用UICollectionView
- 利用TweenPosition 动画制作直角动画播放。
- 123面试题
- LRU缓存介绍与实现 (Java)