传送门

题目大意:

有n(\(\le 15\))个作业,每个作业有个name, deadline(截止日期),cost(做作业花的时间),如果没有按时完成某个作业,惩罚分数为超出的时间,求一个合理的顺序使得惩罚分数最小,如果有多个方案分数相同,输出字典序最小的。

题目分析

看到\(n \le 15\)可知状压dp:dp[S]表示完成S状态的最小惩罚分数,转移也较为简单:$$dp[i | (1 << (j - 1))] = min(dp[S | (1 << (j - 1))], dp[i] + getTime(i) + cost[j] - deadline[j])$$。因为要输出方案,于是记录一个from数组表示这个状态是从哪个状态转移来的。又因为要求字典序最小,现将name排序,这样在转移时如果\(dp[i | (1 << (j - 1))] == dp[i] + getTime(i) + cost[j] - deadline[j])\),并且\(i | (1 << (j - 1)) < from[i]\),那么\(from[i] = i | (1 << (j - 1))\),来保证字典序最小。

code

#include<bits/stdc++.h>
using namespace std; const int N = 20, S = 33000, OO = 0x3f3f3f3f;
int n, dp[S], T, from[S];
vector<int> ans;
struct node{
string name;
int dl, cost;
inline bool operator < (const node &b) const {
return name < b.name;
}
}task[N]; inline int getTime(int s){
int ans = 0;
for (int i=0; (1<<i)<=s; i++)
if ((1<<i)&s)
ans += task[i + 1].cost;
return ans;
} inline void init(){
memset(dp, OO, sizeof dp), dp[0] = 0;
memset(from, 0, sizeof from);
ans.clear();
} inline int find(int x){
int l = 1, r = 15;
while (l<=r) {
int mid = (l + r) >> 1;
if (1<<(mid-1) == x) return mid;
else if (1<<(mid-1) > x) r = mid - 1;
else l = mid + 1;
}
return 0;
} int main(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
cin >> T;
while(T--){
init();
cin >> n;
for (int i=1; i<=n; i++) cin >> task[i].name >> task[i].dl >> task[i].cost;
sort(task + 1, task + n + 1);
for (int i=0; i<(1<<n); i++) {
for(int j=1; j<=n; j++) {
if (i&(1<<(j-1))) continue;
if (dp[i|(1<<(j-1))] > dp[i] + max(0, getTime(i) + task[j].cost - task[j].dl)) {
from[i|(1<<(j-1))] = i;
dp[i|(1<<(j-1))] = dp[i] + max(0, getTime(i) + task[j].cost - task[j].dl);
}
else if(dp[i|(1<<(j-1))] == dp[i] + max(0, getTime(i) + task[j].cost - task[j].dl)) {
if(i < from[i|(1<<(j-1))]) from[i|(1<<(j-1))] = i;
}
}
}
cout << dp[(1<<n)-1] << endl;
int now = (1<<n)-1;
while(now) {
int diff = now ^ (from[now]);
int pos = find(diff);
// cout << now << " " << from[now] << " " << diff << " " << pos << endl;
ans.push_back(pos);
now = from[now];
}
for(int i=ans.size()-1; i>=0; i--) cout << task[ans[i]].name << endl;
}
return 0;
}

HDU1074 Doing Home Work - 状压dp的更多相关文章

  1. kuangbin专题十二 HDU1074 Doing Homework (状压dp)

    Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  2. HDU1074 Doing Homework(状压dp)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题意:给定有n门课的作业,每门课交作业有截止时间,和完成作业所花费的时间,如果超过规定时间完成,每超 ...

  3. HDU1074:Doing Homework(状压DP)

    Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  4. dp,状压dp等 一些总结

    也就作业几题而已,分析一下提醒 最重要的就是,记住,没用的状态无论怎么转移最后都会是没用的状态,所以每次转移以后的有值的状态都是有用的状态. 几种思考方向: 第一种:枚举当前的状态,转移成另外一个状态 ...

  5. 对状压dp的见解

    看了好几篇博客,终于对一些简单的状压dp有了点了解.就像HDU1074. 有个博客:https://blog.csdn.net/bentutut/article/details/70147989 感觉 ...

  6. 算法复习——状压dp

    状压dp的核心在于,当我们不能通过表现单一的对象的状态来达到dp的最优子结构和无后效性原则时,我们可能保存多个元素的有关信息··这时候利用2进制的01来表示每个元素相关状态并将其压缩成2进制数就可以达 ...

  7. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  8. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  9. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

随机推荐

  1. python登录验证程序

    自己写的一个python登录验证程序: 基础需求: 让用户输入用户名密码 认证成功后显示欢迎信息 输错三次后退出程序 升级需求: 可以支持多个用户登录 (提示,通过列表存多个账户信息) 用户3次认证失 ...

  2. Flask项目之手机端租房网站的实战开发(三)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...

  3. amazeui学习笔记--css(布局相关1)--网格Grid

    amazeui学习笔记--css(布局相关1)--网格Grid 一.总结 基本使用 1.div+class布局:amaze里面采取的就是div+class的布局方式  <div class=&q ...

  4. C语言深度解剖读书笔记

    开始本节学习笔记之前,先说几句题外话.其实对于C语言深度解剖这本书来说,看完了有一段时间了,一直没有时间来写这篇博客.正巧还刚刚看完了国嵌唐老师的C语言视频,觉得两者是异曲同工,所以就把两者一起记录下 ...

  5. 具体解释ebs接口之客户配置文件导入(二)

    ------------------------------------ -- 1a. Setup the Org_id ------------------------------------ ex ...

  6. window.print()打印网页(一)

    有时候需要将网页内容打印到纸上,最简单的一种方法是用window对象的print方法. window.print()默认打印当前网页的所有部分.(除了背景,默认打印都是白底黑字,如果有特别的设置 要另 ...

  7. LA 2678 – Subsequence

    看到限时3S,自己写了一个二重循环的,然后华丽的 TLE...T T 瞄了瞄书上,作者的思路果然是很好.膜拜中. 他只枚举了终点,然后用二分查找. 用到了lower_bound函数,这个lower_b ...

  8. Snail—UI学习之自己定义标签栏UITabBarController

    这里的背景跟上面的差点儿相同 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkF ...

  9. Spring Cloud项目

    如何使用windows版Docker并在IntelliJ IDEA使用Docker运行Spring Cloud项目   如何使用windows版Docker并在IntelliJ IDEA使用Docke ...

  10. [Node.js] Testing ES6 Promises in Node.js using Mocha and Chai

    Writing great ES6 style Promises for Node.js is only half the battle. Your great modules must includ ...