codevs 2144 砝碼稱重 2
題目描述 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
思路:就是個很簡單的dfs,但複雜度問題需要處理一下,需要用到剪枝。
首先我們可以將砝碼按從大到小排序,求出字尾和,每次我們搜到乙個砝碼,如果把這個砝碼後面的所有砝碼都用上也到不了m,那我們就可以把後面的剪掉,複雜的會大大降低。
以下是我的記錄:
33分是暴搜,44分是小優化,66分是加字尾和,100分是排序。
題解:
#include
#include
#include
using
namespace
std;
int n;
long
long m;
long
long a[50];
int ans=1e9;
long
long pre[50];
bool vis[50];
int gg=0;
long
long cmp(long
long a,long
long b)
void dfs(int x,long
long sum,int tot)
if(sum+pre[x]return;
}if(x>n||tot>ans||sum>m)
for(int i=0;i<=1;i++)
else
}}int main()
sort(a+1,a+n+1,cmp);
for(int i=n;i>=1;i--)
dfs(1,0,0);
printf("%d\n",ans);
return
0;}
Codevs 2144 砝碼稱重 2
時間限制 1 s 空間限制 16000 kb 題目等級 鑽石 diamond 題解有n個砝碼,現在要稱乙個質量為m的物體,請問最少需要挑出幾個砝碼來稱?注意乙個砝碼最多只能挑一次 輸入描述 input description 第一行兩個整數n和m,接下來n行每行乙個整數表示每個砝碼的重量。輸出描述 ...
刷題記錄 codevs2144 砝碼稱重 2
典型的折半列舉法 本質上是用空間換時間的思想,把一半的資料搜過之後用陣列儲存起來,搜另一半的時候就可以直接使用了 這樣就可以把時間複雜度由乘轉變為和 效率改善非常大哦 include include include include include include define maxn 35 usi...
2144 砝碼稱重 2
時間限制 1 s 空間限制 16000 kb 題目等級 鑽石 diamond 題解 description 有n個砝碼,現在要稱乙個質量為m的物體,請問最少需要挑出幾個砝碼來稱?注意乙個砝碼最多只能挑一次 輸入描述 input description 第一行兩個整數n和m,接下來n行每行乙個整數表示...