简单规划dp sumsets

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



理解两个点:第一个就是滚动数组;
第二个就是dp[]含义;

滚动数组,思维还是二维的,表现形式是一维。注意滚动数组内层循环要从大的开始,因为这是一种迭代,外层循环每循环一次d[j]就会改变,之前的就会被覆盖。
至于为什么要从大的开始呢?因为从小的开始d[j] j 0...C,之后有dp[j-w[i]]就不会使用上层循环,而是会用这层循环前面更新的值,这样就错了。//提示:这个用于01背包!!!!此题是完全背包用不到

dp[j]这个含义是变成j,需要多少步。自己可以跟进一下。
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[25];
const int mo=1000000000;
int dp[1100000];
void pow1()
{
    a[0]=1;
    for(int i=1;i<21;i++)
    {
        a[i]=a[i-1]*2;
    }
    return;
}

int main()
{
    int n;
    cin>>n;
    pow1();
    dp[0]=1;
    for(int i=0;i<21;i++)
    {
        if(a[i]>n) break;
        for(int j=a[i];j<=n;j++)
        {
            dp[j]=(dp[j]+dp[j-a[i]])%mo;
        }
    }
    printf("%d\n",dp[n]);
    return 0;
}

  





猜你喜欢

转载自www.cnblogs.com/EchoZQN/p/10180323.html