悬关,蒟蒻折半搜WA求调
查看原帖
悬关,蒟蒻折半搜WA求调
308800
Polynswin楼主2024/8/14 15:51
#include<bits/stdc++.h>
#define mmt(a,b) memset(a,b,sizeof(a))
#define test(x) cout<<#x<<" = "<<x<<endl
#define endl '\n'
#define enter putchar(endl)
#define int long long
using namespace std;
const int inf=0x3f3f3f3f,N=30;
int n, k, s, maxn, ans, cnt;
int a[N], p[N], Test[N];
map<int, int> f;
int dp[N][N]; //数字lsh后为i且使用贴纸小于j次贴纸的方案数 
void init(int s)
{
	p[1] = 1;
	for(int i=2; p[i-1] * i <= s; ++i) p[i] = p[i-1] * i;
}
void dfs(int t, int tot, int sum, int len)
{
	if(tot > s) return;
	if(t > len || sum >= k )
	{
		if(!f.count(tot)) f[tot] = ++cnt, Test[cnt] = tot;
		++ dp[ f[tot] ][sum];
		return;
	}
	dfs(t+1, tot, sum, len);
	dfs(t+1, tot + a[t], sum, len);
	if(p[a[t]] != -1) dfs(t+1, tot + p[a[t]], sum + 1, len);
}
void dfs2(int t, int tot, int sum, int len)
{
	if(tot > s) return;
	if(t > len || sum >= k)
	{
		if(f.count(s - tot))ans += dp[ f[s - tot] ][k - sum];
		return;
	}
	dfs2(t+1, tot, sum, len);
	dfs2(t+1, tot + a[t], sum, len);
	if(p[a[t]] != -1) dfs2(t+1, tot + p[a[t]], sum + 1, len);
}
signed main()
{
	int i,j;
	for(i=0; i<N; ++i)
		p[i] = -1;
	cin>>n>>k>>s;
	for(i=1; i<=n; ++i)
		cin>>a[i];
	init(s);
	cnt = 0;
	int len = n >> 1;
	dfs(1, 0, 0, len);
//	for(i=1; i<=cnt; ++i)
//	{
//		printf("%d: ", Test[i]);
//		for(j=0; j<=k; ++j)
//			ffout(dp[i][j], ' ');
//		enter;
//	}
	for(i=1; i<=cnt; ++i)
		for(j=1; j<=k; ++j)
			dp[i][j] += dp[i][j-1];
	dfs2(len+1, 0, 0, n);
	ffout(ans);
	return 0;
}


2024/8/14 15:51
加载中...