挑战程序设计 DP POJ 3181

来源:互联网 发布:淘宝网上怎么买药 编辑:程序博客网 时间:2024/05/18 13:31

题目链接


题目大意:完全背包


思路 : dp[i+1][j] = dp[i][j] + dp[i][j-i]


注意:会爆long long,要用两个long long 数组,一个存储高位,另一个存储低位


#include <iostream>#include <cstdio>#include <cstring>using namespace std;const long long M = 1000000000000000;int main(){    int n,k;    long long dp[110][1010],a[110][1010];    while(~scanf("%d%d", &n, &k))//n元钱,k种硬币    {        memset(dp, 0, sizeof dp);        memset(a, 0, sizeof a);                dp[1][0] = 1;//表示前1种钱币前的0种钱币凑成0元只有一种可能                for(int i = 1; i <= k; i++)            for(int j = 0; j <= n; j++)                if(j >= i)                {                    dp[i+1][j] = (dp[i][j] + dp[i+1][j-i])%M;                    a[i+1][j] = a[i][j] + a[i+1][j-i] + (dp[i][j] + dp[i+1][j-i])/M;                }                else                {                    dp[i+1][j] = dp[i][j];                    a[i+1][j] = a[i][j] + (dp[i][j])/M;                }        if(a[k][n])            printf("%lld%015lld\n", a[k+1][n], dp[k+1][n]);        else            printf("%lld\n",dp[k+1][n]);    }    return 0;}/*1.前面i种硬币已经凑成j元 dp[i][j]2.前面i种硬币凑成j-k*i元 加上k*i凑成j*/


阅读全文
0 0