题意:n件物品,给你x个箱子,每个箱子的容量为w,问这些箱子能否装下这n件物品。
解法:枚举物品搜索每一个箱子,找到就放没找到就回溯(挪动其他物品)。
优化:1、物品从大到小排序,大的先放下,可以避免多次回溯(挪动)。2、枚举到第 l 个物品时,只需要在前 l 个箱子找合适的箱子,因为最坏的情况就是前 l 个物品(<w)最多放前 l 个箱子。
好像还有种状压dp的解法待续。
#include<stdio.h> #include<string.h> #include<math.h> #include<queue> #include<algorithm> #include<iostream> #include<map> #define inf 0x3f3f3f3f #define ll long long #define maxx 5000000 #define mod 2147493647//注意这是一个ll型的数,会爆int using namespace std; int a[30] ; int b[30] ; int n , x , w ; int ok ; bool cmp(int a, int b) { return a > b ; } void dfs(int l) { if(ok) return ; if(l >= n)//表示n个物品全部放入箱子中 { ok = 1 ; return ; } for(int i = 0 ; i < x && i <= l ; i++)/优化2 { if(w - b[i] >= a[l]) { b[i] += a[l]; dfs(l+1); b[i] -= a[l]; } } } int main() { int t ; scanf("%d" , &t); while(t--) { int flag = 0 ; ll sum = 0; scanf("%d%d%d" , &n , &x , &w); for(int i = 0 ; i < n ; i++) { scanf("%d" , &a[i]); if(a[i] > w) { flag = 1 ; } sum += a[i]; } if(flag || sum > 1ll * x * w)//特判 { cout << "No" << endl ; } else { ok = 0 ; sort(a , a+n , cmp);//优化1 dfs(0); if(ok) cout << "Yes" << endl ; else cout << "No" << endl ; } } return 0 ; }