邮票问题
【问题描述】
设有已知面额的邮票m种,每种有n张,用总数不超过n张的邮票,能从面额1开始,最多连续组成多少面额。(1≤m≤100,1≤n≤100,1≤邮票面额≤255)
【输入格式】
第一行:m,n的值,中间用一空格隔开。
第二行:A[1..m](面额),每个数中间用一空格隔开。
【输出格式】
连续面额数的最大值
【输入样例】stamp.in
3 4
1 2 4
【输出样例】stamp.out
14
using namespace std;
int n,m,i,j,k;
int c[256];
//面额
int a[31001];
//递推数组
bool b1;
void readfile()//读入数据
{
cin >> m >> n;
b1 = true;
for (i = 1;
i <= m;
i++)
{
cin >> c[i];
if (c[i] == 1) b1 = false;
}
}
void work()
{
if (b1 == true) cout << "MAX=0";
//不存在面额1时输出无解
else
{
i = 1;
a[i] = 1;
do
{
i++;
for (j = 1;
j <= m;
j++)
if (((i % c[j] == 0) && ((i / c[j]) < a[i])) || (a[i] == 0))
a[i] = i / c[j];
//判断它能否被题目给定面额整除
for (j = 1;
j <= i/2;
j++)
if (a[j] + a[i-j] < a[i])
a[i] = a[j] + a[i-j];
//寻找(1<=j<=i),使a[j]+a[i-j]值最小
}
while ((a[i] <= n) && (a[i] != 0));
cout << i-1;
//输出
}
}
int main ( )
{
readfile() ;
work();
return 0;
}
【算法分析】
一看到这个题目,给人的第一感觉是用回溯算法,从面额1开始,每种面额都用回溯进行判断,算法复杂度并不高,但是当m,n取到极限值100时,程序明显超时,因此,回溯算法在这里并不可取。 能否用递推完成呢?我们有一个思路:从面额1开始,建立递推关系方程,就用范例来说吧,面额1,2,4只用1张邮票行了,面额3可以表示为面额1,2的邮票和1+1=2,面额5有两种表示方式min(面额1+面额4,面额2+面额3),照此类推,递推关系方程不难建立,就拿邮票问题来说,以下是递推的一种方法:
【邮票问题】这种递推方法虽然简单,由于1<=邮票面额<=255,1<=n<=100,因此MAX值最多可达到25500,25500次循环里必定还有嵌套循环,因此算法不加优化,很难在规定时间内得出最优值。这就需要递推的算法优化。 一味递推不寻求算法优化,速度较之搜索提高不少,但一旦数据规模过大,很难在规定时间内得出最优值。 这种递推方法原理是:对于某种要求得到的面额,判断它能否被题目给定面额整除,再寻找(1<=j<=i),使A[j]+A[i-j]值最小,求出凑成某种面额最少邮票数,算法虽然简单,但还可以进一步优化。何不将用m种面额邮票作循环,建立递推关系式:A[i]=MAX(A[I-C[j]]+1),于是当取到极限值时,程序减少了约1.6*10^8次循环,递推优化作用不言而喻。
下面是改进后的程序:
#include
#include
using namespace std;
int x[256];
int pieces[30001];
int m,n,i,j;
int main()
{
cin >> m >> n;
for (i = 1;
i <= m;
i++)
cin >> x[i];
memset(pieces,0,sizeof(pieces));
int maxx = 0;
do//递推循环
{
maxx++;
for (i = 1;
i <= m;
i++)
if (maxx - x[i] >= 0)
{//循环,建立递推关系式PIECES[i]=MAX(PIECES[I-X[j]]+1)
if (pieces[maxx] == 0) pieces[maxx] = pieces[maxx-x[i]] + 1;
if (pieces[maxx]>pieces[maxx-x[i]]+1) pieces[maxx] = pieces[maxx-x[i]]+1;
}
if ((pieces[maxx] == 0) || (pieces[maxx] > n))
{
cout << maxx - 1;
break;
}}
while (true);
return 0;
}
推荐阅读
- 宽容谁
- 我要做大厨
- parallels|parallels desktop 解决网络初始化失败问题
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘