华师一附中OI组
标题:
P1021 邮票面值设计
[打印本页]
作者:
admin
时间:
2018-5-26 20:32
标题:
P1021 邮票面值设计
https://www.luogu.org/problemnew/show/P1021
题目描述
给定一个信封,最多只允许粘贴 N 张邮票,计算在给定 K (N+K≤15 )种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX ,使在 1 至 MAX 之间的每一个邮资值都能得到。
例如, N=3 ,K=2 ,如果面值分别为 1 分、 4 分,则在 1 分~ 6 分之间的每一个邮资值都能得到(当然还有 8 分、 9 分和 12 分);如果面值分别为 1 分、 3 分,则在 1分~ 7 分之间的每一个邮资值都能得到。可以验证当 N=3 , K=2 时, 7 分就是可以得到的连续的邮资最大值,所以 MAX=7 ,面值分别为 1 分、3 分。
输入输出格式
输入格式:
2 个整数,代表 N , K 。
输出格式:
2 行。第一行若干个数字,表示选择的面值,从小到大排序。
第二行,输出“ MAX=S ”, S 表示最大的面值。
输入输出样例
输入样例#1:
3 2
输出样例#1:
1 3
MAX=7
作者:
倚窗倾听风吹雨
时间:
2018-8-21 16:58
#include<iostream>
using namespace std;
int n,k,f[1000],a[17],ans[17],r;
void dfs(int x)
{
if(x>k)
{
int o;
for(o=1;f[o-1]<=n;o++)
{
f[o]=99999;
for(int i=1;i<=k && o>=a[i];i++)
f[o]=min(f[o],f[o-a[i]]+1);
}
o-=2;
if(r<o)
{
r=o;
for(int i=1;i<=k;i++)
ans[i]=a[i];
}
return;
}
for(int i=a[x-1]+1;i<=a[x-1]*n+1;i++)
{
a[x]=i;
dfs(x+1);
}
}
int main()
{
cin>>n>>k;
a[1]=1;
dfs(2);
for(int i=1;i<=k;i++)
cout<<ans[i]<<" ";
cout<<endl;
cout<<"MAX="<<r<<endl;
return 0;
}
复制代码
作者:
吴语林
时间:
2018-8-21 21:43
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
int n,k,a[10000],ans[10000],maxn=-0x3f3f3f3f;
int suan(int x)
{
int f[10000];
f[0]=0;
for(int i=1;i<=a[x]*n;i++)
f[i]=0x3f3f3f3f;
for(int i=1;i<=x;i++)
for(int j=a[i];j<=a[x]*n;j++)
f[j]=min(f[j],f[j-a[i]]+1);
for(int i=1;i<=a[x]*n;i++)
if(f[i]>n)
return i-1;
return a[x]*n;
}
void dfs(int num,int ma)
{
if(num==k)
{
if(ma>maxn)
{
maxn=ma;
for(int i=1;i<=k;i++)
ans[i]=a[i];
}
return;
}
for(int i=a[num]+1;i<=ma+1;i++)
{
a[num+1]=i;
dfs(num+1,suan(num+1));
}
}
int main()
{
scanf("%d%d",&n,&k);
a[1]=1;
dfs(1,n);
for(int i=1;i<=k;i++)
printf("%d ",ans[i]);
printf("\nMAX=%d",maxn);
return 0;
}
复制代码
作者:
admin
时间:
2018-8-22 19:37
怎么好像比我的药复杂?看我的程序:
//NOIP99邮票问题
#include<iostream>
#include<iomanip>
using namespace std;
int a[10],b[10],s[1000];
//S[i]表示贴到面值为i至少需要几张邮票
int n,k,maxs,i,t;
int getmax(int l)
{
int i,j,p,q,r ;
for (i=2; i<=999; i++)
{
r=s[i-1]+1;//任何一种面值均可以由前面一个加上一张一分的
j=2; //从第二个邮票面值开始试
p=i-a[j]; //假定由i-a[j]+当前的面值贴出
while ((p>=0)&&(j<=l))
{
q=s[p]+1; //如此贴出
if (r>q) r=q;//检测最小
j++;p=i-a[j];
}
s[i]=r;if (s[i]>n) break;
}
return i-1;
}
void dfs(int i)
{
int j,temp=getmax(i-1);
if (i>k)
{
if (temp>maxs){maxs=temp;for (int ii=0; ii<=9; ii++) b[ii]=a[ii];}
}
else
for (j=a[i-1]+1; j<=temp+1; j++){a[i]=j;dfs(i+1);}
}
int main()
{
cin>>n>>k;
a[1]=1;maxs=1;
s[0]=0;s[1]=1;
dfs(2);
for (i=1; i<=k; i++) cout<<b[i]<<' ';
cout<<endl<<"MAX="<<maxs;
}
复制代码
作者:
admin
时间:
2018-8-22 19:37
怎么好像比我的药复杂?看我的程序:
//NOIP99邮票问题
#include<iostream>
#include<iomanip>
using namespace std;
int a[10],b[10],s[1000];
//S[i]表示贴到面值为i至少需要几张邮票
int n,k,maxs,i,t;
int getmax(int l)
{
int i,j,p,q,r ;
for (i=2; i<=999; i++)
{
r=s[i-1]+1;//任何一种面值均可以由前面一个加上一张一分的
j=2; //从第二个邮票面值开始试
p=i-a[j]; //假定由i-a[j]+当前的面值贴出
while ((p>=0)&&(j<=l))
{
q=s[p]+1; //如此贴出
if (r>q) r=q;//检测最小
j++;p=i-a[j];
}
s[i]=r;if (s[i]>n) break;
}
return i-1;
}
void dfs(int i)
{
int j,temp=getmax(i-1);
if (i>k)
{
if (temp>maxs){maxs=temp;for (int ii=0; ii<=9; ii++) b[ii]=a[ii];}
}
else
for (j=a[i-1]+1; j<=temp+1; j++){a[i]=j;dfs(i+1);}
}
int main()
{
cin>>n>>k;
a[1]=1;maxs=1;
s[0]=0;s[1]=1;
dfs(2);
for (i=1; i<=k; i++) cout<<b[i]<<' ';
cout<<endl<<"MAX="<<maxs;
}
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2