u220 生日禮物

2022-05-22 04:54:11 字數 1568 閱讀 9329

time limit: 1 second

memory limit: 128 mb

一對雙胞胎兄妹同一天過生日,這一天,他們的朋友給他倆送來了禮物,每個人送的禮物都是2本書,一本給哥哥,一本給妹妹,但沒有說

明哪本是給妹妹的,哪本是給哥哥的,每本書都有自己的價值,為了避免衝突,讓你來分配,要求使得兩人所獲得書本的價值和之間的

差距盡可能的小。

例如,有4個禮物:(3,5),(7,11),(8,8),(2,9),可以把3,7,8,2分配給妹妹,其餘的給哥哥,價值差為:5+11+8+9-3-7-8-2=13;如果把3,7

,8,9給妹妹,其餘的給哥哥,價值差為:3+7+8+9-5-11-8-2=1,這是最好的方案。

輸入檔案gift.in的第一行包含乙個正整數n,表示禮物的數量,接下來n行,每行兩個整數,表示每份禮物兩本書的價值(價值範圍在1到300之間)。

輸出檔案gift.out包含乙個非負整數,表示最小的價值差。

對於20%的資料,有n≤20; 對於40%的資料,有n≤50; 對於100%的資料,有n≤150。

4

3 57 11

8 82 9

1
【題解】

這題是把揹包用作乙個工具。來判斷出2*n個數字按照規則不同的組合會產生的最後總價值可能是什麼。

動態轉移方程這樣寫

for (int i = 1; i<= n;i++)

for (int j = 300*150+10;j>=0;j--)

if (f[j])

其中f乙個bool型的一維陣列。

然後我們之所以遇到乙個f[j]就把f[j]置為false,是因為。要保證每乙個禮物都被用到。

比如f[4]是前兩個禮物可能達到的值,我們在更新第四個禮物的時候會遇到f[4]為true,但是我們不能用他來更新f[4+a[i][0]]或f[4+a[i][1]],因為這樣我們會有第三個禮物沒有用。直接跳到了第4個禮物。這樣會導致最後有一些數字是在沒有用滿n個數字的情況下累加得到的。最後得到2*n個數字不同組合可能達到的累加和之後。我們累加所有的數字之和為dd,然後從dd/2開始列舉一直遞增。直到f[i]為真。然後用k記錄這個i。則dd-k就是另外乙個數字。因為我們是從dd/2開始列舉的,可以肯定,這兩個數字一定是最接近的。

最後輸出兩個數字之差就可以了。

【**】

#include #include int n,a[151][2],dd = 0;

bool f[300*150 + 10] = ;

int main()

//將揹包當做工具,獲取最後能累加到哪些數字

int k;

for (int i = (dd / 2);i <=dd;i++) //從dd/2開始列舉,直到找到乙個數字 他可以由n個數字累加得到

if (f[i])

int temp = dd-k; //這是另外乙個數字

if (temp > k) //根據大小關係輸出他們的差就好了。

printf("%d",temp-k);

else

printf("%d",k-temp);

return 0;

}

1005 生日禮物

題目描述 description 輸入描述 input description 輸入的第一行包含2個整數n 1 n 8 m 1 m 10 表示有n種不同型別的本子和m種小寒喜歡的顏色。接下來乙個n m的矩陣。第i行第j列的整數aij表示在第i種型別的本子中包含小寒喜歡的顏色j的紙有aij 1 aij...

codevs1005 生日禮物

時間限制 1 s 空間限制 128000 kb 題目等級 gold 輸入描述 input description 輸入的第一行包含2個整數n 1 n 8 m 1 m 10 表示有n種不同型別的本子和m種小寒喜歡的顏色。接下來乙個n m的矩陣。第i行第j列的整數aij表示在第i種型別的本子中包含小寒喜...

NOIP2006 生日禮物

題目描述 一對雙胞胎兄妹同一天過生日,這一天,他們的朋友給他倆送來了禮物,每個人送的禮物都是2本書,一本給哥哥,一本給妹妹,但沒有說明哪本是給妹妹的,哪本是給哥哥的,每本書都有自己的價值,為了避免衝突,讓你來分配,要求使得兩人所獲得書本的價值和之間的差距盡可能的小。例如,有4個禮物 3,5 7,11...