题目1209:最小邮票数
-
题目描述:
-
有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值。
如,有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
算法分析
for(int j = m;j>=num[i];j--){ //must from m to num[i]
dp[j] = std::min(dp[j],dp[j-num[i]]+1);
}
表示在第i个邮票加入后,从m值到num[i]值的最小邮票数,
一定要从m到num[i],由多到少,因为邮票的数量是固定的。
std::min(dp[j],dp[j-num[i]]+1);
min里面的dp[ j ], dp[ j-num[i] ]都是只有前i-1个邮票的情况下组成的最小数,如果从num[i]开始更新,那么随着i增加到后面dp[ j-num[i] ]表示的就是前i个邮票的情况下组成的最小数,再+1,第i个邮票就重复了。
std::min(dp[j],dp[j-num[i]]+1);
当前的最小数 是j总值下前i-1个邮票所能组成的最小数,j-num[i]总值前i-1个邮票所能组成的最小数+1 的最小值,也就是前i-1个邮票的最小个数 和 包含第i个邮票的最小个数 的最小值。
类似题目
普通背包问题
题目1364:v字仇杀队
题目1462:两船载物问题
题目1455:珍惜现在,感恩生活
题目1209:最小邮票数
题目1420:Jobdu MM分水果
项目安排类题目
题目1499:项目安排
题目1463:招聘会
题目1434:今年暑假不AC
资源无限求最大值的题目。
题目1494:Dota
源程序
//============================================================================
// Name : judo1209.cpp
// Author : wdy
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <cmath>
using namespace std;
int INF = 1<<30;
void minNum(int m,int n){
int *dp = new int[m+1];
dp[0] = 0;
for(int i = 1;i<=m;i++)
dp[i] = INF;
int *num = new int[n];
for(int i = 0;i<n;i++)
std::cin>>num[i];
for(int i = 0;i<n;i++){
for(int j = m;j>=num[i];j--){ //must from m to num[i]
dp[j] = std::min(dp[j],dp[j-num[i]]+1);
}
}
if(dp[m]<INF)
std::cout<<dp[m]<<std::endl;
else
std::cout<<0<<std::endl;
}
void minNumnew(int m,int n){
int *dp = new int[m+1];
dp[0] = 0;
for(int i = 1;i<=m;i++)
dp[i] = INF;
int num;
for(int i = 0;i<n;i++){
std::cin>>num;
for(int j = m;j>=num;j--){ //must from m to num[i]
dp[j] = std::min(dp[j],dp[j-num]+1);
}
}
if(dp[m]<INF)
std::cout<<dp[m]<<std::endl;
else
std::cout<<0<<std::endl;
}
void judo(){
int m = 0;
int n = 0;
while(std::cin>>m>>n){
minNumnew(m,n);
}
}
int main() {
judo();
return 0;
}
/**************************************************************
Problem: 1209
User: KES
Language: C++
Result: Accepted
Time:160 ms
Memory:3632 kb
****************************************************************/
普通背包问题
题目1364:v字仇杀队
题目1462:两船载物问题
题目1455:珍惜现在,感恩生活
题目1209:最小邮票数
题目1420:Jobdu MM分水果
项目安排类题目
题目1499:项目安排
题目1463:招聘会
题目1434:今年暑假不AC
资源无限求最大值的题目。
题目1494:Dota