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;
  }
}
原文地址:https://www.cnblogs.com/dowson/p/3276876.html