1014 題目大意:
            兩個娃子分彈珠,有六種可能(1-6)的好壞程度的彈珠,給定每種好壞彈珠的數量,求是否存在使好壞度總和均分的分配方案。
      1026 題目大意:
            一臺出納機,根據不同的金額請求“盡量”吐出更多的金額代券,最高等值。問給定一個金額數量,和機器內不同面額代券的存,
  量,問機器能吐出逼近請求的最高面值總和是多少。

      題目模型很明顯,很容易聯系到多重背包。對于第一題,首先將彈珠價值總和減半表示為v,然后構造一個v容量背包,題目等價于詢問
該背包的最大存入方案是否能使存入總重量恰好等于v?轉移方程: dp[i][v]=Max( dp[i-1][v], dp[i-1][v-k*w[j]]+k*c[i] | w[i] = c[i], 0<=k<=maxK  )。
同理第二題的轉移方程與1014基本一樣,物品收益即為物重,dp結果即為v容背包最大置入量。

      題目數據很弱,據說硬搜能過。。。 不過還是按照多重背包的優化技巧來做,即用二進制拆分物品數,容易證明這樣的拆分能保證最優性
和正確性。時間復雜度O(C*V*logN)。 對于O(C*V)算法,可以參考 《國家集訓隊2009論文集淺談幾類背包題 》中單調隊列優化DP的技巧。

 1014:

 1#include<cstdio>
 2#include<cstdlib>
 3#include<cstring>
 4#define max(a,b) (a>b)?a:b;
 5#define MAXV 20000*6+1
 6int dp[MAXV];
 7int nk[6];
 8
 9int main(){
10    int i,k,min,v;
11    int cnt,sum;
12    int _case=0;
13    while(1){
14        for(sum=i=0;i<6;i++{
15            scanf("%d",&nk[i]);
16            sum+=nk[i]*(i+1);
17        }

18        if!nk[0& !nk[1& !nk[2& !nk[3& !nk[4& !nk[5] ) break;
19        _case++;
20        if( _case!=1 ) printf("\n");
21        if( sum%2 ){
22            printf("Collection #%d:\n",_case);
23            printf("Can't be divided.\n");
24        }

25        else{
26            sum/=2;
27            memset(dp,0,sizeof(int)*(sum+1));
28            for(i=0;i<6;i++){
29                cnt=1;
30                k=(sum/(i+1)>=nk[i])?nk[i]:sum/(i+1);
31                while(k){
32                    if( cnt>k ) cnt=k;
33                    k-=cnt;
34                    min=cnt*(i+1);
35                    for(v=sum;v>=min;v--)
36                        /* 對每一個拆分數 cnt,單獨做 0/1背包 */
37                       dp[v]=max(dp[v],dp[v-cnt*(i+1)]+cnt*(i+1));
38                    cnt<<=1;
39                }

40            }

41            if( sum == p[sum] ) {
42                printf("Collection #%d:\n",_case);
43                printf("Can be divided.\n");
44            }

45            else {
46                printf("Collection #%d:\n",_case);
47                printf("Can't be divided.\n");
48            }

49        }

50    }

51    return 0;
52}

53