第二題
描述 description
新一年度的貓狗大戰通過sc(星際爭霸)這款經典的遊戲來較量,野貓和飛狗這對冤家為此已經準備好久了,為了使戰爭更有難度和戲劇性,雙方約定只能選擇terran(人族)並且只能造機槍兵。
比賽開始了,很快,野貓已經攢足幾隊機槍兵,試探性的發動進攻;然而,飛狗的機槍兵個數也已經不少了。野貓和飛狗的兵在飛狗的家門口相遇了,於是,便有一場腥風血雨和陣陣慘叫聲。由於是在飛狗的家門口,飛狗的兵補給會很快,野貓看敵不過,決定撤退。這時飛狗的兵力也不足夠多,所以沒追出來。
由於不允許造醫生,機槍兵沒辦法補血。受傷的兵只好忍了。555-
現在,野貓又攢足了足夠的兵力,決定發起第二次進攻。為了使這次進攻給狗狗造成更大的打擊,野貓決定把現有的兵分成兩部分,從兩路進攻。由於有些兵在第一次戰鬥中受傷了,為了使兩部分的兵實力平均些,分的規則是這樣的:1)兩部分兵的個數最多只能差乙個;2)每部分兵的血值總和必須要盡可能接近。現在請你編寫乙個程式,給定野貓現在有的兵的個數以及每個兵的血格值,求出野貓按上述規則分成兩部分後每部分兵的血值總和。
輸入格式 input format
第一行為乙個整數n(1<=n<=200),表示野貓現在有的機槍兵的個數。以下的n行每行乙個整數,表示每個機槍兵的血格(1<=ai<=40)。
輸出格式 output format
只有一行,包含兩個數,即野貓的每部分兵的血值總和,較小的乙個值放在前面,兩個數用空格分隔。
樣例輸入 sample input
樣例輸出 sample output
35 52
時間限制 time limitation
各個測試點1s
分析揹包問題的變形
首先要正確理解題意:分成兩隊人,人數最多相差1,就是要把總人數均分,一隊為n div 2,另一對為n-n div 2
用搜尋的話,只需列舉構造一兵的情況即可,總的狀態數大約為c(n)(n div 2),前兩組資料都可以搜過,資料中還有一種特殊情況,就是所有兵的攻擊力相同。如果騙分程式的話,最多可得30分。
正解當然是動態規劃。
如果我們將選擇的人數也看成一種體積的話,之後類似裝箱問題,將最優性問題轉化為判定性問題,可以寫出下面的方程:
f[i,j,k]表示前i個人中選了j個人,能否達到k的攻擊力。為boolean型別
f[i,j,k]:=f[i-1,j,k] or f[i-1,j-1,k-a[i]]
顯然之和第i個人選不選有關,所以說是揹包問題的變形。如果是三維的方程,由題目中的資料範圍大概是200*100*40*200(注意,題目中特別強調最大攻擊力是有提示性的,給出了k迴圈的上界(j*40),大約305mb(高二的小盆友會算記憶體嗎?)
毫無選擇,必須優化。根據0/1揹包的原理,我們可以壓縮一維狀態:
f[j,k]:=f[j,k] or f[j-1,k-a[i]]
當然j和k都需要倒序迴圈!
計算一下時間複雜度,大約是10^7
這道題不是很難,基本符合noip的要求,但是需要一定的思維量和對揹包問題的深刻理解。
program liukeke;var a:array[1..200] of longint;
f:array[0..200,0..8000] of boolean;
n,i,sum,k,j,n2:longint;
begin
readln(n);
for i:=1 to n do
begin
readln(a[i]);
inc(sum,a[i]);
end;
n2:=n div 2;
f[0,0]:=true;
for i:=1 to n do
for j:=n2 downto 0 do
for k:=j*40 downto a[i] do
f[j,k]:=f[j,k] or f[j-1,k-a[i]];
for i:=(sum div 2) downto 0 do
if f[n2,i] then
begin
write(i,' ',sum-i);
break;
end;
end.
反思這道題中的揹包是抽象的,要抽象出一維體積,將問題完美的轉化為二維揹包。
有時,最優性問題很難求解,要把最優性問題轉化成判定性問題。
kaggle貓狗大戰
kaggle貓狗大戰 kaggle上的貓狗大戰,即對貓狗的分類 沒有特徵資料,只有,所以只能運用神經網路對其訓練 看了大量的kaggle上的公開例子,大多運用tensorflow或者keras建立神經網路,因為最近在學習torch,因此,想用torch建立卷積神經網路進行建模 但整個過程遇到了很多坑...
洛谷 貓狗大戰
初見安 這裡是傳送門 洛谷p1489 貓狗大戰 乙個挺冷門的題啊 也蠻有意思的。把n個數劃分成兩部分,讓兩部分的數的總和的差值盡量小。其實一眼dp,但是要往正解的方向去想是有點點難度的 明顯我們確定乙個集合,另乙個集合也就可以確定了。思考暴力一點的做法 如果我們可以列舉乙個集合的所有可能性,是不是就...
動態規劃 揹包
揹包經典問題 揹包問題01 乙個揹包容積為t 0 t 2000 現在有n 0 如下 includeusing namespace std int s 1005 bool f 3000 int main 揹包問題02 若每種物品有無限多個。從這n種物品中選取若干個裝入揹包內,使揹包所剩的空間最小。請求...