Stamps ans Envelope Sive UVA - 242

(
||{集合x}表示x中元素1||x中元素2||...||x的最后一个元素
||(a,b)表示a||b
)

ans[i][j][k]表示考虑前i种邮票时取j个邮票能否得到面值k
ans[i][j][k]= ||{ans[i-1][j-p][k-p*a[i]]}(0<=p<=j,p*a[i]<=k)
ans[i][j][k]= ||(ans[i-1][j][k],ans[i-1][j-1][k-a[i],...,ans[i-1][j-p][k-p*a[i]])
ans[i][j-1][k-a[i]]= ||(ans[i-1][j-1][k-a[i],...,ans[i-1][j-p][k-p*a[i]])
因此
ans[i][j][k]= ||(ans[i-1][j][k],ans[i][j-1][k-a[i]]) j、k从小到大
因此
ans[j][k]= ||(ans[j][k],ans[j-1][k-a[i]]) i、j、k从小到大

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int s,n;
 6 struct Stamp
 7 {
 8     int data[1100],ans1,data1[1100];
 9     int& operator[](int x)
10     {
11         return data[x];
12     }
13     int operator[](int x) const
14     {
15         return data[x];
16     }
17     void init()
18     {
19         memcpy(data1,data,sizeof(data1));
20         sort(data+1,data+data[0]+1);
21         bool ans2[11][1100];
22         bool ans[1100];
23         memset(ans,0,sizeof(ans));
24         memset(ans2,0,sizeof(ans2));
25         int i,j,k;
26         ans2[0][0]=true;
27         for(i=1;i<=data[0];i++)
28             for(j=1;j<=s;j++)
29                 for(k=data[i];k<=j*data[i];k++)
30                     ans2[j][k]|=ans2[j-1][k-data[i]];
31         for(i=1;i<=s*data[data[0]]+1;i++)
32             for(j=1;j<=s;j++)
33                 ans[i]|=ans2[j][i];
34         for(i=1;i<=s*data[data[0]]+1;i++)
35             if(ans[i]==false)
36             {
37                 ans1=i-1;
38                 break;
39             }
40     }
41     friend bool operator<(const Stamp& a,const Stamp& b)
42     {
43         if(a.ans1>b.ans1)
44             return true;
45         else if(a.ans1<b.ans1)
46             return false;
47         if(a[0]<b[0])
48             return true;
49         else if(a[0]>b[0])
50             return false;
51         //int x[11],y[11];
52         //memcpy(x,a.data,sizeof(x));
53         //memcpy(y,b.data,sizeof(y));
54         //sort(x+1,x+x[0]+1);
55         //sort(y+1,y+y[0]+1);
56         int i;
57         for(i=a[0];i>=1;i++)
58             if(a[i]<b[i])
59                 return true;
60             else if(a[i]>b[i])
61                 return false;
62         return false;
63     }
64     void print()
65     {
66         printf("max coverage =%4d :",ans1);
67         for(int i=1;i<=data[0];i++)
68             printf("%3d",data1[i]);
69         puts("");
70     }
71 }st[11];
72 int num_st;
73 int main()
74 {
75     int i,j;
76     scanf("%d",&s);
77     while(s!=0)
78     {
79         num_st=0;
80         scanf("%d",&n);
81         for(i=1;i<=n;i++)
82         {
83             scanf("%d",&st[++num_st][0]);
84             for(j=1;j<=st[num_st][0];j++)
85                 scanf("%d",&st[num_st][j]);
86             st[num_st].init();
87         }
88         int temp=1;
89         for(i=2;i<=num_st;i++)
90             if(st[i]<st[temp])
91                 temp=i;
92         st[temp].print();
93         scanf("%d",&s);
94     }
95     return 0;
96 }

 

posted @ 2018-04-09 22:19  hehe_54321  阅读(158)  评论(0编辑  收藏  举报
AmazingCounters.com