Sumsets
Time Limit: 2000MS | Memory Limit: 200000K | |
Total Submissions: 17159 | Accepted: 6760 |
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).
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
首先写出前几个数据,然后可以发现:
1.若n为奇数,则ans[n]的每种组合至少有1个1,将所有组合对齐排列,去掉一列1以后,剩下的组合即为ans[n]的组合,所以ans[n] = ans[n-1];
2.若n为偶数,分类讨论:
1)若组合中全为偶数,则这种组合的可能性有ans[n/2]个;
2)若组合中含有1,则至少有2个1,同理这种组合的可能性有ans[n-2]个;
综上,ans[n] = ans[n/2]+ans[n-2];
---------------------------------------------------------
第一次考虑用记忆化递归,结果超时了,程序如下:
<span style="font-size:18px;">#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <bitset>
#include <list>
#include <sstream>
#include <set>
#include <functional>
using namespace std;
#define INT_MAX 1 << 30
#define MAX 100
typedef unsigned long long ll;
int n;
ll ans[1000001];
void solve()
{
ans[1] = 1;
ans[2] = 2;
for (int i = 3; i <= n; i += 1){
if (i % 2 == 0){
ans[i] = ans[i/2]+ans[i-2];
}else{
ans[i] = ans[i-1];
}
}
}
int main(int argc, char const* argv[])
{
scanf("%d",&n);
solve();
printf("%lld\n",ans[n]%1000000000);
return 0;
}</span>
第二次用打表法,从前到后依次算出结果,ac,程序如下
<span style="font-size:18px;">#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <bitset>
#include <list>
#include <sstream>
#include <set>
#include <functional>
using namespace std;
#define INT_MAX 1 << 30
#define MAX 100
typedef unsigned long long ll;
int n;
ll ans[1000002];
void solve()
{
ans[1] = 1;
ans[2] = 2;
for (int i = 3; i <= n; i += 1){
if (i%2 == 0){
ans[i] = (ans[i/2]+ans[i-2])%1000000000;
}else{
ans[i] = ans[i-1];
}
}
}
int main()
{
scanf("%d",&n);
solve();
printf("%lld\n",ans[n]);
return 0;
}</span>