codevs 2144 砝碼稱重 2(搜尋 剪枝)

2021-07-24 11:32:22 字數 1312 閱讀 8404

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行每行乙個整數表示...