ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

papamelon 305. 求和方案 Sumsets

2022-09-04 23:33:33  阅读:222  来源: 互联网

标签:方案 const 组合 int 305 long papamelon Sumsets dp


https://www.papamelon.com/problem/305

给你一个数N,只能用2的幂次求和组成,问总共有多少种方案.

输入
包含多组测试数据,输入以EOF作为结束标志.
每组测试数据包含一个整数NN.
1≤N≤1,000,000
输出
输出一个整数. 由于结果可能会非常大,因此输出末尾的九位数.
样例 1
输入
7
输出
6

例子说明
7 =
1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+2+2
1+2+2+2
1+2+4
1+1+1+4

一种方法是观察找规律
所有的n都有可以由上一个数的所有组合方案+1得到自己的一种组合方案
假设dp[x]表示x的2次幂数的组合方案数
那么dp[x]一部分可以由dp[x-1]转化而来
当x为偶数的时候 x的2次幂组合可以从 x/2的2次幂组合所有元素乘以2转化,而且和dp[x-1]的方案不重合
综上所述
当x为偶数的时候 dp[x] = dp[x/2]+dp[x-1]
当x为奇数的时候 dp[x]=dp[x-1]

#include <iostream>

using  namespace std;

const int N = 1000010;
long long dp[N];
int n;

void solve() {
	dp[0] = 0; dp[1] = 1; dp[2] = 2; dp[3] = 2; dp[4] = 4;

	for (int i = 5; i <= n; i++) {
		if (i % 2 == 0) {
			dp[i] = dp[i - 1] + dp[i / 2];
		}
		else {
			dp[i] = dp[i - 1];
		}
		dp[i] = dp[i] % 1000000000;
	}

	cout << dp[n] << endl;

}

int main()
{
	cin >> n;

	solve();

	return 0;
}

另一种解法从背包的角度来看待
dp[x][y]表示在可选取(20,21,...z^x)的多个元素下 组合成y的方案数
那么可得dp[x][y] = dp[x-1][y-2x]+dp[x-1][y-2*2x]+...+dp[x-1][y-z*2^x]
还可以优化成1维数组,代码如下

#include <iostream>

using  namespace std;

const int N = 1000010;
long long dp[N];
int n;
const int MOD = 1000000000;

int main() {
	cin >> n;
	dp[0] = 1;

	for (int i = 1; i <= n; i <<= 1) {
		for (int j = 1; j <= n; j++) {
			if (j >= i) {
				dp[j] += dp[j - i];
				dp[j] %= MOD;
			}
		}
	}

	cout << dp[n] << endl;

	return 0;
}

我的视频题解空间

标签:方案,const,组合,int,305,long,papamelon,Sumsets,dp
来源: https://www.cnblogs.com/itdef/p/16656221.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有