POJ 2229 Sumsets

题意:大致为求2的幂次集组成数n的组成方法的个数

1. 使用完全背包dp直接求解,这样的复杂度为o(nlogn)

#include<iostream>
#include<cstdio>
using namespace std;
const int MAX_N = 1000000;
const int T = 1000000000;
int n;
int dp[MAX_N+1];
int a[20];
int main () {
    scanf("%d", &n);
    int m = 0;
    a[0] = 1;
    dp[0] = 1;
    while(a[m] <= n) {
        m++;
        a[m] = 2 * a[m-1];
    }
    for(int i = 0; i < m; i++) {
        for(int j = 1; j <= n; j++) {
            if(j >= a[i]) dp[j] = (dp[j] + dp[j - a[i]]) % T;
        }
    }
    printf("%d\n", dp[n]);
     return 0;
} 

2.利用规律(我是找不到。。。)

   对于奇数n来说dp[n] = dp[n-1],对于偶数的n来说,它的组成可分为两类,有1和没1的,有1的数量为dp[n-1],没1的为dp[n/2],则dp[n] = dp[i-1]+dp[i/2];

代码:

#include<iostream>
#include<cstdio>
using namespace std;
const int MAX_N = 1000000;
const int T = 1000000000;
int n;
int dp[MAX_N+1];
int main () {
    scanf("%d", &n);
    int m = 0;
    dp[0] = 1;
    for(int i = 1; i <= n; i++) {
        if(i%2) dp[i] = dp[i-1];
        else dp[i] = (dp[i-1] + dp[i/2])%T;
    } 
    printf("%d\n", dp[n]);
     return 0;
} 

 

posted on 2018-03-19 10:08  kindleheart  阅读(167)  评论(0编辑  收藏  举报