Big Event in HDU——動態規劃之01揹包

現在,我們都知道計算機學院是HDU最大的系。但是,也許你不知道2002年計算機學院曾被分爲計算機學院和軟件學院。
分裂絕對是HDU的一件大事!同時,這也是一件麻煩事。所有設施必須減半。首先,對所有設施進行評估,如果兩個設施具有相同的價值,則認爲它們是相同的。假設有N(0<N<1000)種設施(不同值,不同類型)。
輸入:
輸入包含多個測試用例。每個測試用例以一個數字N開頭(0<N<=50——不同設施的總數)。接下來的N行分別包含一個整數V(0<V<=50——設施的值)和一個整數M(0<M<=100——設施的相應數量)。你可以假設所有的V都是不同的。以負整數開頭的測試用例終止輸入,並且不處理此測試用例。
輸出:
對於每種情況,打印包含兩個整數A和B的一行,分別表示計算機學院和軟件學院的值。A和B應該儘可能相等。同時,你應該保證A不小於B。
Sample Input
2
10 1
20 1
3
10 1
20 2
30 1
-1
Sample Output
20 10
40 40

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int V,N,weight[10002],v[10002];
long int f[100002];
int OnePack()  //0-1揹包的主要思想
{
    memset(f,0,sizeof(f));
    for(int i=0;i<N;i++)
    {
        for(int j=V;j>=weight[i];j--)
            f[j]=max(f[j],f[j-weight[i]]+v[i]);
    }
    return f[V];
}

int main()
{
    int t,a,b,x,y,z;
    while(scanf("%d",&t)&&t>0)
    {
        N=V=0;  //每次揹包的N和V都要更新
        int i=0;
        while(t--)
        {
            scanf("%d%d",&a,&b);
            N+=b;
            V+=a*b;
            while(b--)
            {
                v[i]=a;  //記錄每件物品的價值
                weight[i]=a;  //記錄每件物品的體積,這裏的價值和所佔體積是同一個值
                i++;
            }
        }
        z=V;
        V/=2;
        x=max(OnePack(),z-OnePack());  //最大的設施價值放前面
        y=min(OnePack(),z-OnePack());
        cout<<x<<" "<<y<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章