版权声明: 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;
}