哈尔滨理工大学软件学院ACM程序设计全国邀请赛 C Coin

来源:互联网 发布:模糊图像边缘检测算法 编辑:程序博客网 时间:2024/04/29 02:22

题意:有n个硬币,价值总和为m,问硬币可以凑成1 ~ m的所有价值 的方案总数为多少


思路:dp题,设dp[i][j][k]表示:用i个硬币能凑成1 ~ j且最大面值为k的方案数,那么增加一个面值为add(add >= k)的硬币时, 则有dp[i + 1][j + add][add] += dp[i][j][k],注意add的值不能超过j + 1,理由是当add > j + 1时,无论怎样都凑不出j + 1, j + 2 .... add - 1的价值


#include<cstdio>#include<cstring>#include<algorithm>typedef long long ll;const ll mod = 2 * 1e9 + 7;const int maxn = 210;using namespace std;int T, n, m;ll dp[maxn][maxn][maxn];void init() {    memset(dp, 0, sizeof dp);    dp[1][1][1] = 1;    for(int i = 1; i <= 199; i++) {        for(int j = 1; j <= 200; j++) {            for(int k = 1; k <= 200; k++) {                if(!dp[i][j][k]) continue;                for(int add = k; add + j <= 200 && add < j + 2; add++) {                    dp[i + 1][j + add][add] += dp[i][j][k];                    dp[i + 1][j + add][add] %= mod;                }            }        }    }}int main() {    init();    scanf("%d", &T);    while(T--) {        scanf("%d %d", &n, &m);        ll ans = 0;        for(int i = 1; i <= m; i++) {            ans = (ans + dp[n][m][i]) % mod;        }        printf("%lld\n", ans);    }    return 0;}


0 0
原创粉丝点击