PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)

版权声明: https://blog.csdn.net/Dream_Weave/article/details/81979333

题目链接:点击打开链接

题目大意:点击打开链接

解题思路:DFS + 剪枝 + 计数(若不计数 + 不剪枝都会TLE)。

AC 代码

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a)
#define ssclr(ss) ss.clear(), ss.str("")
#define INF 0x3f3f3f3f
#define MOD 1000000007

using namespace std;

typedef long long ll;

const int maxn=1e4+10;

int n,m,f,len;
int a[maxn], rs[maxn], cnt[150];

void dfs(int sum,int l)
{
    if(f) return;
//    if(sum>m) return; // 1
    if(m==sum)
    {
        for(int i=0;i<l;i++) printf("%d%c",rs[i],i==l-1?'\n':' ');
        f=1;
        return;
    }

    for(int i=0;i<len;i++)
    {
        if(cnt[a[i]]>0)
        {
            if(sum+a[i]>m) return; // 在这里剪枝比在 1 处剪枝效率好很多
            cnt[a[i]]--;
            rs[l]=a[i];
            dfs(sum+a[i],l+1);
            cnt[a[i]]++;
        }
    }
}

int main()
{
    int t;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        scanf("%d",&t);
        // 最后一个测试点,卡这点,因为这会出现比如:1 1 1 2 3 4,而前三个 1 在cnt中分别都有三个,就重复计算了很多次
//        if(t<=m) a[len++]=t, cnt[t]++;
        if(t<=m)
        {
            if(cnt[t]==0) a[len++]=t;
            cnt[t]++;
        }
    }
    sort(a,a+len);
    dfs(0,0);
    if(!f) puts("No Solution");

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dream_Weave/article/details/81979333