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。
43 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...