10数之和为2022

@TOC

1.2022蓝桥杯国赛第一题(10数之和)

题目描述:

  1. 10个数相加的和为2022
  2. 10个数互斥(不能有重复的)
  3. 不能有负数

思路
有2022个物品,它们的编号分别是1到2022,它们的体积分别等于它们的编号。也就是说,有2022种物品,物品体积等于物品编号。

从2022个物品种选取10个物品,满足10个物品的体积之和为2022
用f[i][j][k]表示前i个物品里选择j个物品,体积之和为k的方案数
则对于前i种物品,有两种选择,选或者不选
f[i][j][k]=f[i-1][j][k] 不选
f[i][j][k]=f[i-1][j-1][k-i] 选 (为什么是k-i,因为第i个物品的体积就是i)

#include<iostream>
using namespace std;

long long int f[2023][11][2023];  //表示前2022个物品选择10个物品,体积总和为2022的方案个数  ,,数组下标为1开始,所以使2023,11,2023

int i, j, k;
int main()
{
	for (i = 0; i <= 2022; i++)  //因为体积为0,物品为0的所有情况都只有一种选择,即什么都不选
		f[i][0][0] = 1;
	for (i= 1; i <= 2022; i++)  //枚举所有物品
	{
		for (j = 1; j <= 10; j++)   //选了几个物品
		{
			for (k = 1; k <= 2022; k++)  //枚举体积
			{
				f[i][j][k] = f[i-1][j][k];  //不选第i个物品
				if (k >= i)  //选第i个物品
					f[i][j][k] += f[i-1][j - 1][k - i];
			}
		}
	}
	cout << f[2022][10][2022];
	return 0;
}

当然可以优化一下,由于i都是由i-1转换而来,所以第二维逆序就好了。

#include<iostream>
using namespace std;


long long int dp[11][2025];
//10组物品,每组物品取一个,最后总体积为2022.
//10个数之和为2022
//dp[i][j][k]=dp[i][j][k]+dp[i-1][j-1][k-i]
int main()
{
	dp[0][0] = 1;
	for (int i = 1; i <= 2022; i++)  //2022种物品,每种物品体积等于i
	{
		for (int j = 10; j >= 1; j--)   //取物品个数
			for (int k = i; k <= 2022; k++)   //k是背包容量
				dp[j][k] += dp[j - 1][k - i];   //前i种物品,取j个物品(每种物品只有一个,该物品体积等于i),物品总体积等于k的总方案
	}//对于dp[j][k]的方案,等价于不取i物品,取j个数,总体积恰好为k的方案加上取物品,i取j个数,总体积恰好为k方案
	cout<<dp[10][2022];
	return 0;
}
  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值