POJ 3181 Dollar Dayz(递推,两个long long)

题意:John有N美元,有价格为1~K的工具,可以买的个数不限,问1~K组合出N的方案数。

f[i = 第i中工具][j = 花费为j] = 方案数。

f[i][j] = sigma{ f[i-1][r+k*i] , k ≤ j/i } = f[i][j-i] + f[i-1][j] (优化

这题主要的问题是答案会爆long long。

用两个long long 拼一下就好。

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
//#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int maxn = 1e3+5;

const ll carry = 1e18;
struct dll
{
    ll a,b;
    dll operator + (dll &th){
        dll re = {a+th.a,b+th.b};
        if(re.b >= carry) {
            re.a += re.b / carry;
            re.b %= carry;
        }
        return re;
    }
    void OUT(){
        if(a){
            printf("%I64u%I64u
",a,b);
        }else{
            printf("%I64u
",b);
        }
    }
};

dll f[maxn];

//f[i][j] = sigma f[i-1][r+k*i] = f[i][j-i] + f[i-1][j]

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int N,K;
    cin>>N>>K;
    f[0].b = 1; f[0].a = 0;
    for(int i = 1; i <= K; i++){
        for(int r = 0; r < i; r++){
            for(int j = r+i; j <= N; j += i){
                f[j] = f[j-i] + f[j];
            }
        }
    }
    f[N].OUT();

    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4887312.html