hdu 1074 Doing Homework(状压dp)
题意:小明有n门课,每门课都给出了名字 截止时间 做完需要时间 如果到期没有做完,那么每天每门课要扣除一分,只有昨晚一门课才能去做另一门课
输出扣除分的最小值,并且输出序号字典序最小的那组做作业顺序
分析:只有15门课,可以想到用二进制表示每门课是否做完,那么接下来枚举每个状态就好了
输出方案的话,只要再开个数组记录pre就好了
#include<bits/stdc++.h> using namespace std; const int maxn=15; int dp[1<<maxn],pre[1<<maxn],ttm[1<<maxn]; int b[maxn],c[maxn]; string a[maxn]; void print(int n){ if(!n)return ; print(n-(1<<pre[n])); cout<<a[pre[n]]<<endl; } int main(){ int n,t; cin>>t; while(t--){ cin>>n; for(int i=0;i<n;i++)cin>>a[i]>>b[i]>>c[i]; int bit=1<<n; for(int i=1;i<bit;i++){ dp[i]=INT_MAX; for(int j=n-1;j>=0;j--){ if(!(i&(1<<j)))continue; int res=i-(1<<j); int cnt=ttm[res]+c[j]-b[j]; if(cnt<0)cnt=0; if(cnt+dp[res]<dp[i]){ dp[i]=dp[res]+cnt; ttm[i]=ttm[res]+c[j]; pre[i]=j; } } } cout<<dp[bit-1]<<endl; print(bit-1); } return 0; }