首页 > 代码库 > hdu 1074 Doing Homework (状压dp)
hdu 1074 Doing Homework (状压dp)
题目大意:
给出完成n门功课的所需要的时间和n门功课上交时间的deadline。
如果比deadline 晚交一天就要扣一分。
安排出完成顺序使得扣分最少。
思路分析:
dp[s] 表示完成了s 状态下的功课所扣分的最优解。
对于每一个状态,我们转移的时候将每一门没有完成的功课加入其中,这样就保证了逐一完成。
需要注意的是字典序最小的问题,开始的时候对输入的字符串从小到大排序,每次都从小到大加入状态中。
这样就可以保证加入的状态字典序最小。
还要输出方案,所以ans数组里保存了上一个状态和当前状态加入的功课。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <set> #include <vector> #include <map> #include <string> #define maxn 1005 using namespace std; int dp[1<<15]; int ans[1<<15][2]; int time[1<<15]; struct node { string str; int dead,cost; bool operator < (const node &cmp)const { return str<cmp.str; } }a[20]; void print(int s) { if(s==0)return; print(ans[s][0]); cout<<a[ans[s][1]].str<<endl; } int main() { int T; cin>>T; while(T--) { int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i].str>>a[i].dead>>a[i].cost; sort(a,a+n); memset(dp,0x3f,sizeof dp); memset(time,0,sizeof time); memset(ans,0,sizeof ans); dp[0]=0; for(int s=0;s<(1<<n);s++) { for(int i=0;i<n;i++) { if((1<<i)&s)continue; int c=max(0,time[s]+a[i].cost-a[i].dead); if(dp[s]+c < dp[s|(1<<i)]) { dp[s|(1<<i)]=dp[s]+c; time[s|(1<<i)]=time[s]+a[i].cost; ans[s|(1<<i)][0]=s; ans[s|(1<<i)][1]=i; } } } cout<<dp[(1<<n)-1]<<endl; print(ans[(1<<n)-1][0]); cout<<a[ans[(1<<n)-1][1]].str<<endl; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。