hdu1074Doing Homework
看了大神的题解才知道是怎么做的,状态压缩,好巧妙啊
另外一个大神分析了这道题目为什么用不了贪心做法,我也不知道,因为还没有怎么用过贪心做法,只知道贪心算法在某些题型中才可以用,比如节目安排
压缩状态:
3个状态,
1 0
2 1
3 0 1
1 0
4 2
5 2 0
0 2
6 2 1
1 2
7 0 1 2
1 0 2
2 0 1
0 2 1
2 1 0
1 2 0
最后呢,每种情况都列出来了
看完大神的代码后,我自己也打了一个,一开始提交是错误的,后来对着修改了起来,原来数组开得不够大
#include "iostream" #define INF 10000000; using namespace std; struct{ char name[150]; int data,work; }num[20]; struct{ int day,score,num,pre; }dp[33000]; int s[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}; int main(){ int ncase,n,i,j,reduce,str[110],top=1; cin>>ncase; while(ncase--){ cin>>n; for(i=0;i<n;i++)cin>>num[i].name>>num[i].data>>num[i].work; dp[0].score=0; dp[0].day=0; for(i=1;i<s[n];i++){ dp[i].score=INF; for(j=n-1;j>=0;j--){ if(i&s[j]){ int ans=i-s[j]; reduce=dp[ans].day+num[j].work-num[j].data; if(reduce<0)reduce=0; if(dp[ans].score+reduce<dp[i].score){ dp[i].score=dp[ans].score+reduce; dp[i].day=dp[ans].day+num[j].work; dp[i].num=j; dp[i].pre=ans; } } } } cout<<dp[s[n]-1].score<<endl; for(i=s[n]-1;i>0;){ str[top++]=dp[i].num; i=dp[i].pre; } for(i=top-1;i>=1;i--)cout<<num[str[i]].name<<endl; top=1; } }