货币系统

这道题说坑不坑......说不坑也坑......

【题目描述】

给你一个n种面值的货币系统,求组成面值为m的货币有多少种方案。

【输入】

第一行输入两个正整数n和m,用空格隔开,分别表示货币系统的面值种数和要组成的总面值。

以下n行,每行输入一个正整数,表示货币系统的面值。

【输出】

一行一个数,表示组成目标面值的方案总数。

【输入示例】

3 10

1

2

5

【输出示例】

10

我第一眼看到这道题竟然想到了动规(可喜可贺可喜可贺)

dp[i]=sum(dp[i-面值1],dp[i-面值2]...dp[i-面值n])

但是!我一开始是这么做的

 1 #include<iostream>
 2 using namespace std;
 3 long long n,m;
 4 long long money[18713];
 5 long long dp[10013];
 6 int main()
 7 {
 8     //freopen("money.in","r",stdin);
 9     //freopen("money.out","w",stdout);
10     cin>>n>>m;
11     for(long long i=1;i<=n;i++)
12     {
13         cin>>money[i];
14     }
15     dp[0]=1;
16     for(long long i=1;i<=m;i++)
17     {
18         for(long long j=1;j<=n;j++)
19         {
20             dp[i]=dp[i]+dp[i-money[j]];
21         }
22     } 
23     if(n==0&&m==0)
24     {
25         cout<<0;
26     } 
27     else
28     {
29         cout<<dp[m];    
30     }
31     return 0;    
32 }

看着没有任何问题!对吧?对吧?
但是!你输一下样例就会发现......它特么输出128(呵)

因此我考试的时候交了道深搜然后果不其然的T了......只拿了六十分

如果你输入2、3、1、2的话

你枚举一下,一共有两种可能:1、1、1,1、2

但是你让它算的话,它是把1、2和2、1算成两种可能的。

所以我们要把n踹到外面

 1 #include<iostream>
 2 using namespace std;
 3 long long n,m;
 4 long long money[18713];
 5 long long dp[10013];
 6 int main()
 7 {
 8     //freopen("money.in","r",stdin);
 9     //freopen("money.out","w",stdout);
10     cin>>n>>m;
11     for(long long i=1;i<=n;i++)
12     {
13         cin>>money[i];
14     }
15     dp[0]=1;
16     for(long long i=1;i<=n;i++)
17     {
18         for(long long j=1;j<=m;j++)
19         {
20             dp[j]=dp[j]+dp[j-money[i]];
21         }
22     } 
23     if(n==0&&m==0)
24     {
25         cout<<0;
26     } 
27     else
28     {
29         cout<<dp[m];    
30     }
31     return 0;    
32 }

这样就OK了

在暴风雨中低着头,是为了不让雨水模糊风雨后眼中的彩虹。

原文地址:https://www.cnblogs.com/DK-F/p/9510048.html