hdu Doing Homework(dp位压缩)

来源:互联网 发布:部落冲突蛮王数据 编辑:程序博客网 时间:2024/06/05 07:36
#include <iostream>#include <cstdio>using namespace std;#define  MAXN 16#define  INF (1<<16)+2char sname[MAXN][MAXN<<3];int cost[MAXN],deadline[MAXN];int time[INF],delay[INF],now[INF],pre[INF]; //time表示当前状态的时间,delay表示当前状态罚时,now当前状态结点,pre上一状态的结点void path(int n,int k,int i){    if(i==n) return ;    path(n,pre[k],i+1);    cout<<sname[now[k]]<<endl;}int main(){    int T;    scanf("%d",&T);    while(T--){        int n,i,j,k;        scanf("%d",&n);        for(i=0;i<n;i++){            cin>>sname[i]>>deadline[i]>>cost[i];        }        time[0] = delay[0] = 0;        int max=1<<n;        for(k=1;k<max;k++){            delay[k]=0x7fffffff;            for(i=n-1;i>=0;i--){ //与01背包类似                int j=1<<i;                if(k&j){                    int rem=k-j;                    int redelay=time[rem]+cost[i]-deadline[i]; //计算罚时                    if(redelay<0) redelay = 0; //未超过截至时间                                        if(delay[rem]+redelay<delay[k]){                                                delay[k] = delay[rem]+ redelay;                        time[k] = time[rem] + cost[i]; //当前的时间加上                        now[k]=i;  //j状态的当前结点                        pre[k]=rem;//j状态的上一个结点                    }                }            }        }        cout<<delay[max-1]<<endl;            path(n,max-1,0);    }    return 0;}