读书人

邮票有关问题DP错在哪

发布时间: 2012-02-08 19:52:21 作者: rapoo

邮票问题,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张邮票面值需要排成非递减序列。

高人解释一下,谢谢。

读书人网 >软件架构设计

热点推荐