POJ-2229

Sumsets

Time Limit: 2000MS   Memory Limit: 200000K
Total Submissions: 19599   Accepted: 7651

Description

Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7:

1) 1+1+1+1+1+1+1 
2) 1+1+1+1+1+2 
3) 1+1+1+2+2 
4) 1+1+1+4 
5) 1+2+2+2 
6) 1+2+4

Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000).

Input

A single line with a single integer, N.

Output

The number of ways to represent N as the indicated sum. Due to the potential huge size of this number, print only last 9 digits (in base 10 representation).

Sample Input

7

Sample Output

6

题意:
给出一个整数n,求n有多少种由2的幂次之和组成的方案.

当n为奇数的时候,那么所求的和式中必有1,则dp[n]==dp[n-1];

当n为偶数的时候,可以分两种情况:

1.含有1,个数==dp[n-1];

2.不含有1,这时每个分解因子都是偶数,将所有分解因子都除以二,所得的结果刚好是n/2的分解结果,并且一一对应,则个数为dp[n/2];

AC代码:

 1 //#include<bits/stdc++.h>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5
 6 const long long MOD=1000000000;
 7
 8 int dp[1000010];
 9
10 int main(){
11     ios::sync_with_stdio(false);
12     int n;
13     while(cin>>n&&n){
14         memset(dp,0,sizeof(dp));
15         dp[1]=1;
16         for(int i=2;i<=n;i++){
17             if(i&1){
18                 dp[i]=dp[i-1];
19             }
20             else{
21                 dp[i]=(dp[i-1]+dp[i>>1])%MOD;
22             }
23         }
24         cout<<dp[n]<<endl;
25     }
26     return 0;
27 }
时间: 2024-10-11 20:51:32

POJ-2229的相关文章

poj 2229 【完全背包dp】【递推dp】

poj 2229 Sumsets Time Limit: 2000MS   Memory Limit: 200000K Total Submissions: 21281   Accepted: 8281 Description Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an

POJ 2229 Sumsets (递推&amp;整数划分变形)

http://poj.org/problem?id=2229 思路:假设加数按从小到大的顺序.当n为奇数时,第一个数必须为1,此时f(n)=f(n-1):当n为偶数时,分两种情况讨论,若第一个数为1,则f(n)=f(n-1),若第一个数不为奇数,则所有数都不为奇数,提出一个公因子2出来,就是f(n/2),所以,f(n)=f(n-1)+f(n/2) 完整代码: /*63ms,4300KB*/ #include<cstdio> const int mod = 1e9; const int maxn

POJ 2229(Sumsets)

题目链接:http://poj.org/problem?id=2229 思路:“动态规划”问题 只需要列三个连续数字N即可发现:1.N为奇数时,f(n)=f(n-1)    2.N为偶数时,f(n)=f(n-1)+f(n/2)   因为此时N-1为基数,N-1情况的每一行第一个数一定是1,所以加上一个1时,就相当于在前面直接加一个1或者与 “后面” 的1组成2. ac代码: #include <iostream> #include <algorithm> #include <

POJ 2229 Sumsets(找规律,预处理)

题目 参考了别人找的规律再理解 /* 8=1+1+1+1+1+1+1+1+1 1 8=1+1+1+1+1+1+1+2 2 3 8=1+1+1+1+2+2 8=1+1+1+1+4 4 5 8=1+1+2+2+2 8=1+1+2+4 6 7 8=2+2+2+2 8=2+2+4 8=4+4 8=8 8~9 */ /* 以下引用自博客:http://blog.csdn.net/scorpiocj/article/details/5940456 如果i为奇数,肯定有一个1,把f[i-1]的每一种情况加一个

POJ 2229 Sumsets(简单DP)

Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7: 1) 1+1+1+1+1+1+1 2) 1+1+1+1+1+2 3) 1+1+1

poj 2229 Sumsets 完全背包求方案总数

Sumsets Description Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7: 1) 1+1+1+1+1+1+1 2)

POJ 2229 Sumsets(递推,思考)

/* n = 7 1) 1+1+1+1+1+1+1 2) 1+1+1+1+1+2 3) 1+1+1+2+2 4) 1+1+1+4 5) 1+2+2+2 6) 1+2+4 */ /* 若i为偶数 : 若有 1 ,至少有两个 ---->f[i-2]的情况+两个1, 若没有1 , 将偶数分解/2-----> f[i/2]; 则dp[i] = dp[i / 2] + dp[i-2] 若i为奇数: 必定有 1, dp[i] = 减去1的序列,加上1 则dp[i] = dp[i – 1] */ 1 #in

poj 2229 完全背包变形(求解整数拆分问题)

整数拆分问题:给定一个正整数n,将n拆分为若干数字的和,问有多少种方法? 此题为整数拆分问题的子问题,拆分出的数字要求是2的幂次. 定义dp[i][k]表示枚举到第k个数字时数字i的拆分方案数. 则有状态转移方程: dp[i][k] = dp[i][k - 1] + dp[i - num[k]][k]; 熟悉完全背包的朋友可以看出,这个方程和完全背包的状态转移方程如出一辙,第二维可以省去,只要将i从小到大枚举即可. 1 #include <iostream> 2 #include <cs

DP:Sumsets(POJ 2229)

 数的集合问题 题目大意:给定你一个整数m,你只能用2的k次幂来组合这个数,问你有多少种组合方式? 这一题一看,天啦太简单了,完全背包?是不是? 不过的确这一题可以用完全背包来想,但是交题绝对是TLE,如果真的是完全背包的做法那我就不用等那么多天再发这个坑,这一题的确要用到点奇妙的思想. 首先,我们忽略了这一题的最重要的一个条件,我们使用的数就是2次幂的,那么2次幂的数可以做什么呢?这就是一个数学问题了 不过不要怕,这个数学问题也很好想, 首先:任何一个奇数一定有1来组成,推论:任何偶数都可以只

POJ 2229 计数DP

dp[i]代表是数字i的最多组合数如果i是一个奇数,i的任意一个组合都包含1,所以dp[i] = dp[i-1] 如果i是一个偶数,分两种情况讨论,一种是序列中包含1,因此dp[i]=dp[i-1]一种是序列不包含1,那么序列中的数都是2的倍数,把他们都除以2,序列与i/2序列相同,得到dp[i]=dp[i-1]+dp[i>>1] 1 #include <cstdio> 2 using namespace std; 3 int dp[1000000 + 10]; 4 int mai