Sumsets

来源:互联网 发布:mac微博客户端是什么 编辑:程序博客网 时间:2024/05/22 00:15

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
USACO 2005 January Silver

思路:这题没什么思路,加上数学又学的不好.遂先打表找规律.(1-16)

code:

#include <iostream>#include<cstdio>#include<cmath>#include<cstring>#define M 100using namespace std;int ans[M];int ant;bool vis[10][10][10][10]; // 1 2 4 8void 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=11 Result=1n=21 1 2 Result=2n=31 1 1 1 2 Result=2n=41 1 1 1 1 1 2 2 2 4 Result=4n=51 1 1 1 1 1 1 1 2 1 2 2 1 4 Result=4n=61 1 1 1 1 1 1 1 1 1 2 1 1 2 2 1 1 4 2 2 2 2 4 Result=6n=71 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=6n=81 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=10n=91 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=10n=101 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=14n=111 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=14n=121 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=20n=131 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=20n=141 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=26n=151 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=26n=161 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 1000000typedef 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;}



0 0
原创粉丝点击