邮票问题,DP错在哪?
有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值。
如,有1分,3分,3分,3分,4分五张邮票,要求凑成10分,则使用3张邮票:3分、3分、4分即可。
首先是要求凑成的邮票总值M,M<100
然后是一个数N,N〈20,表示有N张邮票。接下来是N个正整数,分别表示这N张邮票的面值,且以升序排列。
输出:
能够凑成总值M的最少邮票张数。若无解,输出0。
样例输入:
10 5 1 3 3 3 4
样例输出:
3
- C/C++ code
#include<iostream>using namespace std;#define fail 10000const int M = 200;const int N = 20;int c[M][N];//c[i][j]表示面额为i,使用前j张面值时的最少张数int v[N]; //每张邮票的面值int m = 0,n = 0;int dp(){ int i,j; for(i = 0;i <= m;i++) c[i][0] = fail; for(i = 0;i <= n;i++) c[0][i] = 0; int min ; for(i = 1; i <= m;i++){ for(j = 1; j <= n;j++ ){ if(i > v[j]) { c[i][j] = c[i][j-1]; if(c[i][j] > c[i-v[j]][j-1]+1)c[i][j]=c[i-v[j]][j-1]+1; } else c[i][j] = c[i][j-1]; } } if(c[m][n]==fail)c[m][n] = 0; return c[m][n];}int main(){ memset(c,0,sizeof(c)); memset(v,0,sizeof(v)); while(cin>>m>>n){ for(int i = 1;i <= n;i++) cin>>v[i]; cout<<dp()<<endl; memset(c,0,sizeof(c)); } [解决办法]
main没有return呀。定义min没用到呀。
[解决办法]
const int M = 200;
const int N = 20; 你定义了这两个东西
while(cin>>m>>n){
for(int i = 1;i <= n;i++)
cin>>v[i];
cout<<dp()<<endl;
你又输入了m,n,dp()里的m,n一直是0
逻辑问题我不知道了,无解的情况是怎么挑出来的
[解决办法]
为什么无解的情况c[m][n]==fail
为什么把c[i][0]=fail
[解决办法]
我有2个问题,希望帮忙解答一下。
1.c[i][0]=fail; if (c[m][n]==fail){return 0;}
为什么这样做可以判断是否无解。
2.为什么n张邮票面值需要排成非递减序列。
高人解释一下,谢谢。