码迷,mamicode.com
首页 > 其他好文 > 详细

邮票面值设计NOIP1999T

时间:2014-11-07 12:41:20      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   color   ar   os   sp   for   

邮票面值设计NOIP1999T

问题描述
给定一个信封,最多只允许粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值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分。
  
  样例: 
INPUT 
3 2        

OUTPUT
1  3
MAX=7

 

思路:深搜加上dp。每次深搜中j的取值范围从上一次+1到上一次能取到的最大值+1,能减少循环次数。对于最大值的取得情况用dp,类似于背包。

 

bubuko.com,布布扣
#include<iostream>

#include<cstring>

using namespace std;

int n,k,a[41]={0},ansd[41]={0},ans=0,piece[30001]={0};

int rmb(int i)

{

    int j,t,maxx;

    memset(piece,0,sizeof(piece));

    for (j=1;j<=i;++j)

        piece[a[j]]=1;

    maxx=1;

    do

{ 

  ++maxx;

      for (j=1;j<=i;++j)

        if (maxx-a[j]>=0)

        {

if (piece[maxx]==0) piece[maxx]=piece[maxx-a[j]]+1;

if (piece[maxx]>piece[maxx-a[j]]+1) piece[maxx]=piece[maxx-a[j]]+1;

}

  if ((piece[maxx]==0)||(piece[maxx]>n))

       return maxx-1;

    }

    while (true);

}

void dfs(int i,int maxn)

{

int j;

if (i==k+1)

{

if (maxn>ans)

{

ans=maxn;

for (j=2;j<=k;++j)

  ansd[j]=a[j];

}

return;

}

 

for (j=a[i-1]+1;j<=maxn+1;++j)

{

a[i]=j;

maxn=rmb(i);

dfs(i+1,maxn);

}

}

int main()

{

int i;

cin>>n>>k;

a[1]=1;

ansd[1]=1;

dfs(2,n);

for (i=1;i<=k;++i)

  cout<<ansd[i]<<" ";

cout<<endl<<"MAX="<<ans<<endl;

}
RZUC Code

 

邮票面值设计NOIP1999T

标签:style   blog   http   io   color   ar   os   sp   for   

原文地址:http://www.cnblogs.com/Rivendell/p/4080859.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!