Sumsets

HDU 2709

Problem 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
 

Source

思路:這題沒什麼思路,加上數學又學的不好.遂先打表找規律.(1-16)

code:

#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define M 100
using namespace std;
int ans[M];
int ant;
bool vis[10][10][10][10]; // 1 2 4 8
void dfs(int x,int k,int n)
{
    if(x==0)
    {
        int a=0,b=0,c=0,d=0;
        for(int j=0; j<k; ++j)
        {
            if(ans[j]==1)a++;
            if(ans[j]==2)b++;
            if(ans[j]==4)c++;
            if(ans[j]==8)d++;
        }
        if(!vis[a][b][c][d])
        {
             vis[a][b][c][d]=true;
        for(int j=0; j<k; ++j)
            printf("%d ",ans[j]);
            printf("\n");
            ant++;
        }
        return ;
    }
    for(int i=1; i<=n; i*=2)
    {
        if(x-i>=0)
        {
        ans[k]=i;
        dfs(x-i,k+1,n);
        }
    }
}
int main()
{
    freopen("xx.out","w",stdout);
    for(int i=1;i<=16;++i)
    {
         ant=0;
         cout<<"n="<<i<<endl;
         memset(vis,0,sizeof(vis));
         memset(ans,0,sizeof(ans));
         dfs(i,0,i);
         cout<<"Result="<<ant<<endl;
    }
    // cout << "Hello world!" << endl;
    return 0;
}
打表結果:
n=1
1 
Result=1
n=2
1 1 
2 
Result=2
n=3
1 1 1 
1 2 
Result=2
n=4
1 1 1 1 
1 1 2 
2 2 
4 
Result=4
n=5
1 1 1 1 1 
1 1 1 2 
1 2 2 
1 4 
Result=4
n=6
1 1 1 1 1 1 
1 1 1 1 2 
1 1 2 2 
1 1 4 
2 2 2 
2 4 
Result=6
n=7
1 1 1 1 1 1 1 
1 1 1 1 1 2 
1 1 1 2 2 
1 1 1 4 
1 2 2 2 
1 2 4 
Result=6
n=8
1 1 1 1 1 1 1 1 
1 1 1 1 1 1 2 
1 1 1 1 2 2 
1 1 1 1 4 
1 1 2 2 2 
1 1 2 4 
2 2 2 2 
2 2 4 
4 4 
8 
Result=10
n=9
1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 2 
1 1 1 1 1 2 2 
1 1 1 1 1 4 
1 1 1 2 2 2 
1 1 1 2 4 
1 2 2 2 2 
1 2 2 4 
1 4 4 
1 8 
Result=10
n=10
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 2 2 
1 1 1 1 1 1 4 
1 1 1 1 2 2 2 
1 1 1 1 2 4 
1 1 2 2 2 2 
1 1 2 2 4 
1 1 4 4 
1 1 8 
2 2 2 2 2 
2 2 2 4 
2 4 4 
2 8 
Result=14
n=11
1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 2 2 
1 1 1 1 1 1 1 4 
1 1 1 1 1 2 2 2 
1 1 1 1 1 2 4 
1 1 1 2 2 2 2 
1 1 1 2 2 4 
1 1 1 4 4 
1 1 1 8 
1 2 2 2 2 2 
1 2 2 2 4 
1 2 4 4 
1 2 8 
Result=14
n=12
1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 1 2 2 
1 1 1 1 1 1 1 1 4 
1 1 1 1 1 1 2 2 2 
1 1 1 1 1 1 2 4 
1 1 1 1 2 2 2 2 
1 1 1 1 2 2 4 
1 1 1 1 4 4 
1 1 1 1 8 
1 1 2 2 2 2 2 
1 1 2 2 2 4 
1 1 2 4 4 
1 1 2 8 
2 2 2 2 2 2 
2 2 2 2 4 
2 2 4 4 
2 2 8 
4 4 4 
4 8 
Result=20
n=13
1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 1 1 2 2 
1 1 1 1 1 1 1 1 1 4 
1 1 1 1 1 1 1 2 2 2 
1 1 1 1 1 1 1 2 4 
1 1 1 1 1 2 2 2 2 
1 1 1 1 1 2 2 4 
1 1 1 1 1 4 4 
1 1 1 1 1 8 
1 1 1 2 2 2 2 2 
1 1 1 2 2 2 4 
1 1 1 2 4 4 
1 1 1 2 8 
1 2 2 2 2 2 2 
1 2 2 2 2 4 
1 2 2 4 4 
1 2 2 8 
1 4 4 4 
1 4 8 
Result=20
n=14
1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 1 1 1 2 2 
1 1 1 1 1 1 1 1 1 1 4 
1 1 1 1 1 1 1 1 2 2 2 
1 1 1 1 1 1 1 1 2 4 
1 1 1 1 1 1 2 2 2 2 
1 1 1 1 1 1 2 2 4 
1 1 1 1 1 1 4 4 
1 1 1 1 1 1 8 
1 1 1 1 2 2 2 2 2 
1 1 1 1 2 2 2 4 
1 1 1 1 2 4 4 
1 1 1 1 2 8 
1 1 2 2 2 2 2 2 
1 1 2 2 2 2 4 
1 1 2 2 4 4 
1 1 2 2 8 
1 1 4 4 4 
1 1 4 8 
2 2 2 2 2 2 2 
2 2 2 2 2 4 
2 2 2 4 4 
2 2 2 8 
2 4 4 4 
2 4 8 
Result=26
n=15
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 1 1 1 1 2 2 
1 1 1 1 1 1 1 1 1 1 1 4 
1 1 1 1 1 1 1 1 1 2 2 2 
1 1 1 1 1 1 1 1 1 2 4 
1 1 1 1 1 1 1 2 2 2 2 
1 1 1 1 1 1 1 2 2 4 
1 1 1 1 1 1 1 4 4 
1 1 1 1 1 1 1 8 
1 1 1 1 1 2 2 2 2 2 
1 1 1 1 1 2 2 2 4 
1 1 1 1 1 2 4 4 
1 1 1 1 1 2 8 
1 1 1 2 2 2 2 2 2 
1 1 1 2 2 2 2 4 
1 1 1 2 2 4 4 
1 1 1 2 2 8 
1 1 1 4 4 4 
1 1 1 4 8 
1 2 2 2 2 2 2 2 
1 2 2 2 2 2 4 
1 2 2 2 4 4 
1 2 2 2 8 
1 2 4 4 4 
1 2 4 8 
Result=26
n=16
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 
1 1 1 1 1 1 1 1 1 1 1 1 2 2 
1 1 1 1 1 1 1 1 1 1 1 1 4 
1 1 1 1 1 1 1 1 1 1 2 2 2 
1 1 1 1 1 1 1 1 1 1 2 4 
1 1 1 1 1 1 1 1 2 2 2 2 
1 1 1 1 1 1 1 1 2 2 4 
1 1 1 1 1 1 1 1 4 4 
1 1 1 1 1 1 1 1 8 
1 1 1 1 1 1 2 2 2 2 2 
1 1 1 1 1 1 2 2 2 4 
1 1 1 1 1 1 2 4 4 
1 1 1 1 1 1 2 8 
1 1 1 1 2 2 2 2 2 2 
1 1 1 1 2 2 2 2 4 
1 1 1 1 2 2 4 4 
1 1 1 1 2 2 8 
1 1 1 1 4 4 4 
1 1 1 1 4 8 
1 1 2 2 2 2 2 2 2 
1 1 2 2 2 2 2 4 
1 1 2 2 2 4 4 
1 1 2 2 2 8 
1 1 2 4 4 4 
1 1 2 4 8 
2 2 2 2 2 2 2 2 
2 2 2 2 2 2 4 
2 2 2 2 4 4 
2 2 2 2 8 
2 2 4 4 4 
2 2 4 8 
4 4 4 4 
4 4 8 
8 8 
16 
Result=36

可以發現規律了: 當n是奇數的時候,值就等於前面那個偶數的值.n爲偶數的時候,它的值等於前面那個奇數的值再加上它本身/2的那個值

AC code:

#include<iostream>
#include<cstdio>
using namespace std;
#define M 1000000
typedef long long ll;
const int mode=1000000000;
int n;
ll num[M]={0,1,2};
void slove()
{
    int i,j;
    for(i=3;i<=M;++i)
    {
        if(i&1) num[i]=num[i-1];    //奇數就等於前一位的偶數
        else num[i]=(num[i-1]+num[i/2])%mode;//偶數等於前一位+當前數/2
    }
}
int main()
{
    slove();
    while(scanf("%d",&n)!=EOF)
    {
        //printf("%I64d\n",num[n]);
        printf("%I64d\n",num[n]%mode);
        //cout<<num[n]<<endl;
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章