dfs枚举

题意: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 ;
}
posted @ 2020-01-13 23:55  无名菜鸟1  阅读(215)  评论(0编辑  收藏  举报