题解:P1441 砝码称重

思路:

1.搜索参数:当前已经选取的个数;已经放弃的个数
2.搜索剪枝:放弃的比m多,则return
3.搜索边界:如果已选取了n个:如果正好放弃了m个,dp;return
3.搜索内容:(1)不放弃当前砝码
      (2)放弃当前砝码
4.标记:是否被放弃
5.DP:利用背包解决


代码:

#include <iostream>
#include <cstring>
using namespace std;

const int MAXN = 2010;

int n, m, ans;
int a[MAXN], vis[MAXN], f[MAXN];

void dp()
{
    memset(f, 0, sizeof(f));
    f[0] = 1;
    int ret = 0, sum = 0;
    for(int i=0; i<=n; i++)
    {
        if(vis[i])
            continue;
        for(int j=sum; j>=0; j--)
        {
            if(f[j] && !f[j + a[i]])
            {
                f[j + a[i]] = 1;
                ret ++;
            }
        }
        sum += a[i];
    }
    ans = max(ans, ret);
}

void dfs(int get, int give_up)
{
    if(give_up > m)
    {
        return ;
    }
    if(get == n)
    {
        if(give_up == m)
        {
            dp();
        }
        return ;
    }
    dfs(get + 1, give_up);
    vis[get] = 1;
    dfs(get + 1, give_up + 1);
    vis[get] = 0;
}

int main()
{
    cin >> n >> m;
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
    }
    dfs(0, 0);
    cout << ans << endl;
    return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/LonelyFish/p/10629934.html
今日推荐