您的位置:首页 > 其它

hdu 1074 Doing Homework(状压dp)

2017-03-15 14:59 483 查看
题意:小明有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
));
cout<<a[pre
]<<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;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: