【NOIP2021 数列】题解

题目链接

首先dp得从低位向高位枚举,因为高位无论如果使用 2ai 都对低位二进制1的个数无影响,满足dp的无后效性。

dp(k,i,x,y)S 从低的高二进制的前 k 位中,用了数列 a 的前 i 项,且此时 S 中共有 x 个二进制位为1,第 i+1 位进了 y 过去。

则:

dp(k,i,x,y)=j=0nidp(k+1,i+j,x+(y+j&1),y+j>>1)×Ci+jj×vkj

假设这一位有 jaj 满足 aj=k,则下一位就有 i+ja 的元素确定,如果这一位是1,则 x+1,在转移中的 x+(y+j&1) 体现。而进位到下一位的就是 y+j>>1 了。

对于每种方案,其对于答案的贡献为 vkj,而方案相当于在 i+j 个数中插 j 块板,即 Ci+jj

建议用记忆化搜索实现。

Code

// Problem: P7961 [NOIP2021] 数列【民间数据】
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P7961
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define mo 998244353
#define N 40
#define M 110
int n, m, i, j, k; 
int c[M][M], s[M][M]; 
int f[M][N][N][N], v[M], K; 

int count(int x)
{
	int ans=0; 
	while(x) x-=x&-x, ++ans; 
	return ans; 
}

int dfs(int k, int u, int x, int y)
{
	if(u==n)
	{
		// printf("> f[%lld][%lld][%lld][%lld]=%lld\n", k, u, x, y, x+count(y)<=K);
		if(x+count(y)>K) return 0; 
		// printf("----------"); 
		return 1; 
	}
	if(k>m) return 0; 
	if(f[k][u][x][y]!=-1) return f[k][u][x][y]; 
	int ans=0;  
	for(int i=0; i<=n-u; ++i)
	{
		ans=(ans+dfs(k+1, u+i, x+((y+i)&1), (y+i)>>1)
						*s[k][i]%mo*c[u+i][i]%mo)%mo; 
		// printf("%lld %lld\n", s[k][i], c[n-u][i]); 
	}
	f[k][u][x][y]=ans; 
	// printf("f[%lld][%lld][%lld][%lld]=%lld\n", k, u, x, y, f[k][u][x][y]); 
	return f[k][u][x][y]; 
}


signed main()
{
//	freopen("tiaoshi.in","r",stdin);
//	freopen("tiaoshi.out","w",stdout); 
	memset(f, -1, sizeof(f)); 
	n=read(); m=read(); K=read(); 
	for(i=0; i<=m; ++i) v[i]=read(); 
	c[0][0]=1; 
	for(i=1; i<=n; ++i)
		for(j=c[i][0]=1; j<=i; ++j) 
			c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo; 
	for(i=0; i<=m; ++i)
	{
		s[i][0]=1; 
		for(j=1; j<=n; ++j) s[i][j]=(s[i][j-1]*v[i])%mo; 
	}
	printf("%lld\n", dfs(0, 0, 0, 0)); 
	return 0;
}


posted @   zhangtingxi  阅读(387)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示