HDU 1074 Doing Homework状态DP

来源:互联网 发布:棱镜门事件 知乎 编辑:程序博客网 时间:2024/06/10 15:54

此题总状态量很小,可以状态DP

#include <stdio.h>#include <cstring>using namespace std;struct point{char str[110];int cost,dead;}sub[20];int n;int dp[32800],pre[32800],visit[32800],time[32800];void print(int state){if(pre[state]==-1)return;print(state^(1<<(pre[state]-1)));printf("%s\n",sub[pre[state]].str);}int main(){int t,T,sum;scanf("%d",&T);for(t=1;t<=T;t++){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%s %d %d",&sub[i].str,&sub[i].dead,&sub[i].cost);}sum=(1<<n)-1;memset(visit,0,sizeof(visit));dp[0]=0,time[0]=0,pre[0]=-1,visit[0]=1;for(int i=0;i<=sum;i++){for(int j=1;j<=n;j++){if( (i& (1<<(j-1)) ) ==0){int tempun=0,t,cur;if(time[i]+sub[j].cost>sub[j].dead)tempun=time[i]+sub[j].cost-sub[j].dead;tempun+=dp[i];t=time[i]+sub[j].cost;cur=(i| (1<<(j-1)) );if(!visit[cur]){dp[cur]=tempun,pre[cur]=j,time[cur]=t;visit[cur]=1;}else{if(dp[cur]>tempun)      // 因为枚举的时候是按照字典序进行的,所以这里如果相等就不用更新了dp[cur]=tempun,pre[cur]=j,time[cur]=t;}}}}printf("%d\n",dp[sum]);print(sum);}}


 

原创粉丝点击