POJ 3181 Dollar Dayz 完全背包 + 高精度

来源:互联网 发布:淘宝店家查询 编辑:程序博客网 时间:2024/04/28 21:26

定义状态为前i个金币能组合成总金额为j的方案总数

状态转移方程为

和完全背包类似,可以化简成


因为这道题最后会爆long long int

在大神的博客里面学到了一招,将答案拆成两半,用两个dp数组存。一个存高18位,一个存低18位。

#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define MAX_N 1005using namespace std;typedef long long int ll;ll dp1[MAX_N], dp2[MAX_N];//dp1表示高18位,dp2表示低18位ll INF = 1;int main(){    //freopen("1.txt", "r", stdin);    for (int i = 1; i <= 18; i++)        INF *= 10;    ll N, K;    while (cin >> N >> K)    {        int weight[MAX_N];        for (ll i = 1; i <= K; i++)            weight[i] = i;        memset(dp1, 0, sizeof(dp1));        memset(dp2, 0, sizeof(dp2));        for (ll i = 1; i <= K; i++)            for (ll j = 0; j <= N; j++)        {            if (i == 1)                dp2[j] = (j % weight[1] == 0) ? 1 : 0;            else if (j >= weight[i])            {                dp1[j] = dp1[j] + dp1[j - weight[i]] + (dp2[j] + dp2[j - weight[i]]) / INF;                dp2[j] = (dp2[j] + dp2[j - weight[i]]) % INF;            }        }        if (dp1[N])            printf("%I64d", dp1[N]);        printf("%I64d\n", dp2[N]);    }    return 0;}


0 0
原创粉丝点击