問題
【問題描述】
過年的時候,大人們最喜歡的活動,就是打牌了。xiaomengxian不會打牌,只好坐在一邊看著。
這天,正當一群人打牌打得起勁的時候,突然有人喊道:「這副牌少了幾張!」眾人一數,果然是少了。於是這副牌的主人得意地說:「這是一幅特製的牌,我知道整副牌每一張的重量。只要我們稱一下剩下的牌的總重量,就能知道少了哪些牌了。」大家都覺得這個辦法不錯,於是稱出剩下的牌的總重量,開始計算少了哪些牌。由於資料量比較大,過了不久,大家都算得頭暈了。
這時,xiaomengxian大聲說:「你們看我的吧!」於是他拿出膝上型電腦,編出了乙個程式,很快就把缺少的牌找了出來。
如果是你遇到了這樣的情況呢?你能辦到同樣的事情嗎?
【輸入檔案】
第一行乙個整數totalw,表示剩下的牌的總重量。
第二行乙個整數n(1接下來n行,每行乙個整數wi(1<=wi<=1000),表示每一張牌的重量。
【輸出檔案】
如果無解,則輸出「0」;如果有多解,則輸出「-1」;否則,按照公升序輸出丟失的牌的編號,相鄰兩個數之間用乙個空格隔開。
【輸入樣例】
【輸出樣例】
2 4分析
一看題目我們就知道是揹包問題。
注意給出的體積,不是我們要的需要用總體積減去給的體積。
下面可將這個題抽象成乙個裝箱問題,必須裝滿。我們很快會想到用boolean型別的動規,但是這樣只能判斷可行性,對於多解卻無能為力。對此我們換一種方程,讓方程表示方案總數,方程我在這裡不寫了。
我們開乙個陣列path紀錄決策,只有當當前體積的方案數為0時,我們紀錄決策。(想想為什麼)
輸出就是遞迴的輸出,和昨天寫的那個類似,也是揹包問題輸出的一般的基本方法
注意方案數有可能很大,所以我們加一句優化,如果方案數大於10000則變成mod 10000的值,由於我們只需要做判定,所以這樣是不影響結果的。
反思有些時候方程的表示無法滿足題目的要求,我們考慮更換方程的表示,也許只是用這種表示的某個性質,表面上不能直接看出來。這兩天對動規的輸出方案有了點感覺,宗旨就是遞迴,由當前決策推得上一決策。知道推到最初決策在回溯輸出即可
注意揹包問題的變形
code
program liukee;var v:array[1..100] of longint;
f,path:array[0..1000500] of longint;
vtot,n,i,j,sum:longint;
procedure outit(vv:longint);
var i:longint;
begin
if vv=0 then exit;
outit(vv-v[path[vv]]);
write(path[vv],' ');
end;
begin
assign(input,'card.in');reset(input);
assign(output,'card.out');rewrite(output);
readln(vtot);
readln(n);
for i:=1 to n do
begin
readln(v[i]);
inc(sum,v[i]);
end;
vtot:=sum-vtot;
f[0]:=1;
for i:=1 to n do
for j:=vtot downto v[i] do
begin
if f[j-v[i]]<>0 then//注意這裡的順序
begin
if f[j]=0 then
path[j]:=i;
inc(f[j],f[j-v[i]]);
if f[j]>10000 then f[j]:=f[j] mod 10000;
end;
end;
if (f[vtot]=0) then
writeln(0)
else if f[vtot]>1 then writeln(-1)
else outit(vtot);
close(input);
close(output);
end.
新年趣事之打牌
新年趣事之打牌 問題描述 過年的時候,大人們最喜歡的活動,就是打牌了。xiaomengxian不會打牌,只好坐在一邊看著。這天,正當一群人打牌打得起勁的時候,突然有人喊道 這副牌少了幾張!眾人一數,果然是少了。於是這副牌的主人得意地說 這是一幅特製的牌,我知道整副牌每一張的重量。只要我們稱一下剩下的...
新年趣事之打牌
問題描述 過年的時候,大人們最喜歡的活動,就是打牌了。xiaomengxian不會打牌,只好坐在一邊看著。這天,正當一群人打牌打得起勁的時候,突然有人喊道 這副牌少了幾張!眾人一數,果然是少了。於是這副牌的主人得意地說 這是一幅特製的牌,我知道整副牌每一張的重量。只要我們稱一下剩下的牌的總重量,就能...
新年趣事之打牌 DP
新年趣事之打牌 輸入檔案 bagb.in 輸出檔案 bagb.out 簡單對比 時間限制 1 s 記憶體限制 128 mb 題目描述 過年的時候,大人們最喜歡的活動,就是打牌了。xiaomengxian不會打牌,只好坐在一邊看著。這天,正當一群人打牌打得起勁的時候,突然有人喊道 這副牌少了幾張!眾人...