USACO Money Systems Dp 01背包

一道经典的Dp..01背包

定义dp[i] 为需要构造的数字为i 的所有方法数

一开始的时候是这么想的

    for(i = 1; i <= N; ++i){
        for(j = 1; j <= V; ++j){
            if(i - a[j] > 0){
                dp[i] += dp[i - a[j]];
            }
        }
    }

状态存在冗余, 输出的时候答案肯定不对

但只需要改一下两个for循环的顺序即可。

 

Source Code:

/*
ID: wushuai2
PROG: money
LANG: C++
*/
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <vector>
#include <algorithm>
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
#define MOD 1000000007
#define pi acos(-1.0)

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;

template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}
template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}

const double eps = 1e-7      ;
const int M = 660000         ;
const ll P = 10000000097ll   ;
const int INF = 0x3f3f3f3f   ;
const int MAX_N = 20         ;
const int MAXSIZE = 101000000;

ofstream fout ("money.out");
ifstream fin ("money.in");

int V, N, a[30];
ll dp[11000];

int main(){
    int i, j, k, l, m, n, t, s, c, w, q, num;
    fin >> V >> N;
    for(i = 1; i <= V; ++i){
        fin >> a[i];
    }
    dp[0] = 1;
    for(i = 1; i <= V; ++i){
        for(j = a[i]; j <= N; ++j){
            if(j - a[i] >= 0){
                dp[j] += dp[j - a[i]];
            }
        }
    }
    /*
    for(i = 1; i <= N; ++i){
        for(j = 1; j <= V; ++j){
            if(i - a[j] > 0){
                dp[i] += dp[i - a[j]];
            }
        }
    }
    */
    fout << dp[N] << endl;

    fin.close();
    fout.close();
    return 0;
}

 

posted @ 2015-02-21 23:06  Jeremy Wu  阅读(188)  评论(0编辑  收藏  举报