邮票面值设计(NOIP 1999)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/x15696576570/article/details/80217049

很有意思一道题,深搜加递推动态规划:

【问题描述】
  给定一个信封,最多只允许贴N张邮票,计算在给定K(N+K<=40) 种邮票的情况下(所有的邮票数量都足够),如何设计邮票的面值,能得到最大max ,使得1-max之间的每一个邮资值都能得到。
  例如,N=3,K=2,如果面值分别为1分、4分,则在l分至6分之间的每一个邮资值都能得到(当然还有8分、9分和12分):如果面值分别为1分、3分,则在1分至7分之间的每一个邮资值都能得到。可以验证当N=3,K=2时,7分就是可以得到连续的邮资最大值,所以MAX=7,面值分别为l分、3分。
【样例输入】
  N=3 k=2
【样例输出】
  1 3
   MAX=7

#include"iostream"
#include"cstdio"
#include"algorithm"
#include"vector"

using namespace std;

int f[2000000],a[51],b[51],res=0;
int k,n;

void find()
{
	int t=0;
	f[0]=0;
	while(f[t]<=n)
	{
		t++;
		f[t]=9999;
		for(int i=0;i<k;i++)
		{
			if(t>=a[i]&&f[t-a[i]]+1<f[t])
				f[t]=f[t-a[i]]+1;
		}
	}
	if(t-1>res)
	{
		res=t-1;
		for(int i=0;i<k;i++)
		{
			b[i]=a[i];
		}
	}
}

void dfs(int cur)
{
	if(cur==k)
	{
		find();
		return;
	}
	for(int i=a[cur-1];i<a[cur-1]*n+2;i++)
	{
		a[cur]=i;
		dfs(cur+1);
	}
}

int main()
{
	cin>>n>>k;
	a[0]=1;
	dfs(1);
	for(int i=0;i<k;i++)
	{
		cout<<b[i]<<' ';
	}
	cout<<endl<<"MAX="<<res<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/x15696576570/article/details/80217049