数字拆分2022
题目:

思路:
每个数选/不选,物品个数限制,范围到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)
图解:

代码:
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;
}
参考:
蓝桥杯官方书籍
图引百度三维数组

浙公网安备 33010602011771号