首页 > 其他 > 详细

CJOJ P2221 -【中学高重点内容级本】邮票

时间:2017-03-18 23:44:39      阅读:365      评论:0      收藏:0      [点我收藏+]

Description

邮局发行一套票面有n(0<n<=10)种不同面值的邮票。若限每封信所贴的邮票张数不得超过m枚,存在整数r使得用不超过m(0<m<=2n)枚的邮票,可以贴出连续整数1,2,3,…,r值来,找出这种面值数,使得r值最大。

Input

一行,输入N及M

Output

输出R

Sample Input

2 3

Sample Output

7

Solution

按照题目的意思,由于要找出最大能拼出的数,因此要用一个函数dp(),来找出最大能拼出的数,然而要找出这个数,还需要找出这n种邮票分别为多少,所以还需要一个函数dfs(),这个函数用来找这n种邮票。
此时,我们可以用一个数组a[x],来储存第x种邮票的面值为多少,同时,用一个数组f[i]表示要凑出总值为i的最少需要的邮票数,a[x]用于找下一个邮票面值,f[i]用于找当前情况下最大能组成的数值,即max(r)。
详细代码(附带每一步的解释)如下:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 int n,m,a[100],maxr,f[10000];
 7 void init()
 8 {
 9   cin>>n>>m;
10   a[1]=1;
11 }
12 int DP(int n)
13 {
14   int i,j;
15   f[0]=0;
16   for(i=1;;i++)//枚举总值
17     {
18       f[i]=-1;//f[i]存要凑出总值为i的最少需要的邮票数
19       for(j=1;j<=n;j++)//枚举邮票面值a[j]
20     if(i-a[j]>=0/*a[j]可以用来凑i*/ && f[i-a[j]]+1<=m/*加上后邮票数不超过m*/ &&(f[i]==-1 || f[i-a[j]]+1<=f[i])/*可以更新f[i]的值*/)
21       f[i]=f[i-a[j]]+1;//更新f[i]的值
22       if(f[i]==-1)//凑不出来
23     return i-1;//
24     }
25 }
26 void DFS(int p)
27 {
28   if(p>n)//如果面值大于i,那么就不能再往下dfs,已经到了更新答案的时候了
29     {
30       int s=DP(n);//n种邮票面值可以凑出的最大值
31       if(s>maxr)
32     {
33       maxr=s;
34     }
35       return;
36     }
37   int i;//如果还可以往下深搜
38   for(i=a[p-1]+1;i<=DP(p-1)+1;i++)//枚举可以新放的邮票的值,从a[p-1]->目前最大邮票单张面额,dp(p-1)+1->下一张最大单张邮票面额,也就是枚举a[p]可以有的值
39     {
40       a[p]=i;//更新此时a[p]的值
41       DFS(p+1);//对此时已有邮票的单张面额进行深搜,更新a[p+1]的值,或者更新maxr
42     }
43 }
44 
45 int main()
46 {
47 
48   init();
49   DFS(2);
50   cout<<maxr<<endl;
51 }

 

 

CJOJ P2221 -【中学高重点内容级本】邮票

原文:http://www.cnblogs.com/ly-Kirsty/p/6576266.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!