题意: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 ;
}
来源:https://www.cnblogs.com/nonames/p/12190018.html