1. 程式人生 > >2144 砝碼稱重 2 用map離散化hasi+二分搜尋

2144 砝碼稱重 2 用map離散化hasi+二分搜尋

2144 砝碼稱重 2

 時間限制: 1 s  空間限制: 16000 KB  題目等級 : 鑽石 Diamond 題目描述 Description

有n個砝碼,現在要稱一個質量為m的物體,請問最少需要挑出幾個砝碼來稱?

注意一個砝碼最多隻能挑一次

輸入描述 Input Description

第一行兩個整數n和m,接下來n行每行一個整數表示每個砝碼的重量。

輸出描述 Output Description

輸出選擇的砝碼的總數k,你的程式必須使得k儘量的小。

樣例輸入 Sample Input

3 10
5
9
1

樣例輸出 Sample Output

2

資料範圍及提示 Data Size & Hint

1<=n<=30,1<=m<=2^31,1<=每個砝碼的質量<=2^30

//use the map of STL to discretization hasi 
#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
int n,m,a[32],ans=100;
map<int,int> p;
void dfs1(int k,int cur,int sum){
	if(sum>m||cur>n/2) return;
	p[sum]=k;
	dfs1(k+1,cur+1,sum+a[cur+1]);
	dfs1(k,cur+1,sum);
}
void dfs2(int k,int cur,int sum){
	if(sum>m||cur>n) return;
	if(p.find(m-sum)!=p.end()){
		ans=min(ans,p[m-sum]+k);
		return;
	}
	dfs2(k,cur+1,sum);
	dfs2(k+1,cur+1,sum+a[cur+1]);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	scanf("%d",a+i);
	dfs1(0,0,0);
	dfs2(0,n/2,0);
	printf("%d\n",ans);
	return 0;
}


相關推薦

2144 砝碼 2 map離散hasi+二分搜尋

2144 砝碼稱重 2  時間限制: 1 s  空間限制: 16000 KB  題目等級 : 鑽石 Diamond 題解 題目描述 Descrip

CODE【VS】2144 砝碼2(dfs+剪枝)

題目描述 Description 有n個砝碼,現在要稱一個質量為m的物體,請問最少需要挑出幾個砝碼來稱? 注意一個砝碼最多隻能挑一次 輸入描述 Input Description 第

CODEVS 2144 砝碼2

//二分dfs,最後合併 #include<bits/stdc++.h> using namespace std; const int maxn = 400000; int n, m,

wikioi 2144 砝碼 2 STL_map

看似dp,但是資料太大,不過n很小,可以暴力解決。 由於30個數組合情況太多,所以可以分成兩邊,首先預處理前n/2個數能組成哪些數,並且最小消耗多少砝碼,map儲存下來。 然後處理右邊能組合成什麼數,相加就夠了。 注意這樣會漏掉兩種情況,就是光一邊就能組成最終答案的(因為m

wikioi-天梯-提高一等-雜湊表-2144砝碼2

題目描述 Description 有n個砝碼,現在要稱一個質量為m的物體,請問最少需要挑出幾個砝碼來稱? 注意一個砝碼最多隻能挑一次 輸入描述 Input Description 第一行兩個整數n和m,接下來n行每行一個整數表示每個砝碼的重量。

Codevs_P2144 砝碼 2

時間限制: 1 s 空間限制: 16000 KB 題目等級 : 鑽石 Diamond 題目描述 Description 有n個砝碼,現在要稱一個質量為m的物體,請問最少需要挑出幾個砝碼來稱? 注意一個砝碼最多隻能挑一次 輸入描述 Input De

Wikioi 2144 砝碼

用到的技巧就是將它分成前n/2個和後n/2個砝碼 先計算出前n/2個砝碼可以稱出的重量和所用砝碼數量(暴力計算) 存在map中 處理後n/2個砝碼的時候就直接判斷m-當前重量是否可行並更新ans即可 #include<cstdio> #include<ma

砝碼2

題目描述 Description 有n個砝碼,現在要稱一個質量為m的物體,請問最少需要挑出幾個砝碼來稱? 注意一個砝碼最多隻能挑一次 輸入描述 Input Description 第一行兩個整數

砝碼 5個砝碼 天平時,我們希望用盡可能少的砝碼組合稱出儘可能多的重量。

/*砝碼稱重 5個砝碼 用天平稱重時,我們希望用盡可能少的砝碼組合稱出儘可能多的重量。 如果只有5個砝碼,重量分別是1,3,9,27,81。則它們可以組合稱出1到121之間任意整數重量(砝碼允許放在左

NOI題庫--砝碼V2(多重揹包2^n拆分)

以前只會寫多重揹包的原版,渣的不行,為了做此題不得不學習了一下,發現其實也不難,只要理解了方法就好多了(PS:其實和倍增挺像的) 8756:砝碼稱重V2 總時間限制: 1000ms 記憶體限制:

51nod 1837 砝碼【數學,規律】

可能 blank sed gif span nbsp sin pro n-1 題目鏈接:51nod 1837 砝碼稱重 小 Q 有 n 個砝碼,它們的質量分別為 1 克、 2 克、……、 n 克。 他給 i 克的砝碼標上了編號 i (i =

luogu1441 砝碼

true down size mark std ios post pos tdi 搜索+背包就是了 #include <iostream> #include <cstring> #include <cstdio> using namesp

P1441 砝碼

ron 思路 sca 去掉 class sample ret eof 不同的 題目描述 現有n個砝碼,重量分別為a1,a2,a3,……,an,在去掉m個砝碼後,問最多能稱量出多少不同的重量(不包括0)。 輸入輸出格式 輸入格式: 輸入文件weight.in的第1行為有兩

P2347 砝碼 (01背包)

格式 sub base col can span %d spa 輸出 題目描述 設有 1g1g1g 、 2g2g2g 、 3g3g3g 、 5g5g5g 、 10g10g10g 、 20g20g20g 的砝碼各若幹枚(其總重 ≤1000 \le 1000≤1000 ), 輸

洛谷P2347 砝碼

getc org www. ogr ext get tle ati pro 題目 貌似是某年提高組簽到題,六重循環零壓力AC,差點怒踩std 但本蒟蒻決定寫正解——多重背包,果斷20分 原因是寫錯了狀態轉移方程。。。神才知道我咋過的樣例和兩個測試點 扯遠了 多重

洛谷P1411 砝碼

false http 時間 .org 背包 ret code 就是 傳送門 傳送門啦 這個題總體思路就是先搜索在 $ dp $ void dfs(int keep,int now){ //使用 放棄 if(now > m) return;

【練習】砝碼

 P1441 砝碼稱重 思路:dfs列舉去掉哪些砝碼, 01揹包求方案數, 各種情況取max記為ans輸出√ 邊界情況處理不好交了三遍QAQ dp[j] = dp[j] + dp[j - a[i]] 選上這個砝碼的情況+ 不選的情況 1 #include<cstdio>

[P1441]砝碼 (搜尋+DP)

對於我這種蒟蒻,是很不錯的一題了。 dfs搜尋當前狀態 滿足時DP 比較坑的地方就是起始的地方 我一開始從1開始,搜尋寫的是從0開始。 後來就統一用0開始的了。 #include<bits/stdc++.h> #define max(a,b) (a>b?a:b) usi

洛谷1441 砝碼

原題連結 挺水的一道題。 \(DFS\)列舉被刪除的砝碼,每次刪完後進行\(01\)揹包計數,取最大值即可。 這題不需要剪枝即可通過。 我這裡是用連結串列儲存的資料。 #include<cstdio> #include<cstring> #include<algorithm&

洛谷P1441 砝碼(加強版)

題目連結 P1441 砝碼稱重 解題思路: 搜尋/列舉+dp dp過程參考弱化版的P2347 砝碼稱重。 妙啊,真的是妙啊… 感覺這題搜尋和dp結合的恰到好處。利用dfs先枚舉出所有可能的情況,當陣列