洛谷 P1441 砝码称重(深搜+DP)

传送门


题目描述

现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。

输入输出格式

输入格式:
输入文件weight.in的第1行为有两个整数n和m,用空格分隔
第2行有n个正整数a1,a2,a3,……,an,表示每个砝码的重量。

输出格式:
输出文件weight.out仅包括1个整数,为最多能称量出的重量。

输入输出样例

输入样例:
3 1
1 2 2

输出样例:
3

说明

【样例说明】
在去掉一个重量为2的砝码后,能称量出1,2,3共3种重量。

【数据规模】
对于20%的数据,m=0;
对于50%的数据,m≤1;
对于50%的数据,n≤10;
对于100%的数据,n≤20,m≤4,m<n,ai≤100。


没什么好说的吧……
先暴搜,然后用背包统计数量。

#include
#include
#include

bool f[2010];
int n,m,ans;
int a[23];
bool v[23];

int max(int x,int y)
{
    return x>y?x:y;
}

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

void dfs(int yx,int ys)
{
    if(ys>m) return;
    if(yx>n)
    {
        if(ys==m) dp();
        return;
    }
    dfs(yx+1,ys);
    v[yx]=false;
    dfs(yx+1,ys+1);
    v[yx]=true;
}

int main()
{
    memset(v,true,sizeof(v));
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    dfs(1,0);
    printf("%d",ans);
}

你可能感兴趣的:(搜索,DP)