这是个简单的动态规划题,背包问题嘛~首先,把给的邮票按照面额从小到达拍个序,也算是一个小优化吧。理论上能够贴出的最大面额为K*Max,动态转移方程为:
DP[i]=Min ( DP[i-W[j]] + 1 ) (i>=W[j] j=1..N),W[j]代表邮票j的面额,DP[i]存放要达到总面额为i所需最少的邮票数。初始状态:F[0]=0。
#include<cstdio>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int n,k;
int dp[2000006];
int w[60];
int main()
{
freopen("stamps.in","r",stdin);
freopen("stamps.out","w",stdout);
cin>>k>>n;
for(int i=0;i<n;i++)
cin>>w[i];
sort(w,w+n);
int max=w[n-1]*k;
int ii;
//memset(dp,0x7f,sizeof(dp));//这个在数据量不大的时候效率没有for循环高
for(int i=0;i<=max;i++)
dp[i]=100000;
dp[0]=0;
for(ii=1;ii<=max;ii++)
{
for(int j=0;j<n;j++)
{
if(ii>=w[j])
{
if(dp[ii]>dp[ii-w[j]]+1)
dp[ii]=dp[ii-w[j]]+1;
}
}
if(dp[ii]>k && dp[ii]!=100000)
break;
}
cout<<ii-1<<endl;
return 0;
}