头像

欢迎来到我的博客

分享题解与总结

数字拆分2022

题目:

image

思路:

每个数选/不选,物品个数限制,范围到2022,dp

一般背包dp[i][j]的定义是:对前i种物品进行取舍选择,背包容量为j时,所能获得的最大价值

——背包容量限制

此题:

——对1~2022进行取舍选择

——选几个数字 [新增!]

——背包容量为1~2022

解题过程:

三维0/1背包

dp[i][j][k]

  • i 对1~i进行取舍选择
  • j 从前i个数字中选j个数 [新增!]
  • k 选出的数和为k

的方法总数

dp[50][30][400]:含义是——在1~50中选择30个数字,使得和为400的方法总数

状态转移方程:

\(dp[i][j] = \begin{cases} dp[i-1][j][k](i>k) \\ dp[i-1][j][k]+dp[i-1][j-1][k-i](i<=k) \\ \end{cases}\)

\(i∈[1,2022],j∈[1,10],k∈[1,2022]\)

状态压缩:

不难发现dp[i][j][k]只依赖dp[i-1][][],压缩掉i所在维度

初始化:

只需要初始化dp[0][]即可

其中dp[0][0]=1(状态压缩前dp[i][0][0]=1)

图解:

image

代码:

ll dp[15][2050],n=2022,m=10;

int main()
{
	dp[0][0]=1;
	for(int k=1;k<=n;++k)
		dp[0][k]=0;
	for(int i=1;i<=n;++i){//n=2022
		for(int j=10;j>=1;--j){
			for(int k=n;k>=1;--k){
				if(i>k) break;
				else dp[j][k]+=dp[j-1][k-i];
			}
		}
	}
	cout<<dp[10][2022];
	return 0;
}

参考:

蓝桥杯官方书籍

图引百度三维数组

posted @ 2026-07-01 16:43  king_steph1209  阅读(4)  评论(0)    收藏  举报