小y得到了兩張價值不菲的shop購物券,所以他決定去買n件禮物送給朋友們。小y選好了n件禮物,並且它們的**之和恰好為兩張購物券的面值之和。當小y被自己的聰明所折服,高興地去結賬時,他突然發現shop對購物券的使用有非常奸詐的規定:一次只允許使用一張、不找零、不與現金混用。小y身上根本沒有現金,並且他不願意放棄挑選好的禮物。這就意味著,他只能通過這兩張購物券結賬,而且每一張購物券所購買的物品的總**必須精確地等於這張購物券的面額。怎樣才能順利地買回這n件禮物呢?你的任務就是幫助小y確實是否存在乙個購買方案。小y會告訴你其中一張購物券的面額以及所有商品的**,你只需要確定能否找到一種方案使得選出來的物品的**總和正好是這張購物券的面額即可。
輸入有多組資料,每兩行有一組資料。每組資料的第一行為兩個整數n和m,分別表示小y一共挑選了n個物品以及小y的一張購物券的面額為m,接下來的一行有n個用空格隔開的正整數,第i個數表示第i物品的**。
輸出包含若干行,每行乙個單詞」yes」或者」no」,分別代表存在乙個購買方案和不存在乙個購買方案。
對於30%的輸入檔案,所有的n≤20;
對於100%的輸入檔案,所有的n≤40,並且m和物品的總價值不超過2^31-1,測試組數不超過10組,不少於5組。
當我剛看到這道題時,內心時懵逼的??這跟雜湊有什麼關係??並且還往揹包問題想偏了(捂臉)
首先分析一下題目,每種物品有取和不取的可能,不去重的話,複雜度要2^40,直接**。而且陣列不能開到maxint。
嗯,就開始yy。想了很久,終於反應過來,就是取個雜湊值,把同餘的放在vector的陣列裡,就不用取到maxint啦!
但是複雜度的問題始終沒有解決啊。
事實上可以分成兩個部分,分別全排列求和,這樣複雜度就是2*2^20,接著列舉合併求解就好了,這樣就可以過了!
#include
#include
#include
#include
#include
const
int h=9973;
using
namespace
std;
vector
ha[h],hb[h];
int n,m,a[44];
bool ptr;
inline
void recover()
if(l==r) return;
df(l+1,r,w);
df(l+1,r,w+a[l]);
}inline
void dfs(int l,int r,int w)
if(l==r) return;
dfs(l+1,r,w);
dfs(l+1,r,w+a[l]);
}inline
void find()}}
}}int main()
int mid=(1+n)>>1;
df(1,mid,0);
if(mid1,n,0);
if(!ptr)
find();
if(ptr) printf("yes\n");
else
printf("no\n");
}return
0;}
(七)購物券設計
id int unsigned auto increment comment 主鍵 deno decimal 10,2 unsigned not null comment 面值 condition decimal 10,2 unsigned not null comment 訂單滿多少錢可以使用 s...
藍橋杯 2011 購物券(dfs)
公司發了某商店的購物券 1000 元,限定只能購買店中的 m種商品。每種商品的 分別為 m1,m2,要求程式列出所有的正好能消費完該購物券的不同購物方法。程式輸入 第一行是乙個整數 m,代表可購買的商品的種類數。接下來是 m個整數,每個 1行,分別代表這 m種商品的單價。程式輸出 第一行是乙個整數,...
藍橋杯 購物券消費方案 遞迴暴力 解題報告
公司發了某商店的購物券1000元,限定只能購買店中的m種商品。每種商品的 分別為m1,m2,要求程式列出所有的正好能消費完該購物券的不同購物方法。程式輸入 第一行是乙個整數m,代表可購買的商品的種類數。接下來是m個整數,每個1行,分別代表這m種商品的單價 0第一行是乙個整數,表示共有多少種方案 第二...