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

18.04.09 luoguP1021 邮票面值设计

时间:2018-04-09 21:12:58      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:void   include   情况   允许   输入输出   range   class   最大   copy   

题目描述

给定一个信封,最多只允许粘贴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
技术分享图片
 1 #include <iostream>
 2 #include <string>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 
 7 using namespace std;
 8 const int maxn=20;
 9 int n,k;//张数 面值数
10 int maxx=0,kind[maxn],res[maxn];
11 
12 int dp(int t){
13     //初始化f[]
14     int f[5000]={0};//达到连续到某数时需要的最小张数
15     for(int i=1;i<=kind[t]*n;i++)
16         f[i]=9999;
17     for(int i=1;i<=t;i++)
18         for(int j=kind[i];j<=kind[t]*n;j++){
19             f[j]=min(f[j],f[j-kind[i]]+1);
20         }
21     for(int i=1;i<=kind[t]*n;i++){
22         if(f[i]>n)
23             return i-1;
24     }
25     return kind[t]*n;
26 }
27 
28 void dfs(int t,int maxnum){//第几张面值 目前可以连续到多少
29     if(t==k+1)
30        {
31         if(maxnum>maxx)
32         {
33             maxx=maxnum;
34             for(int i=1;i<=k;i++)
35                 res[i]=kind[i];
36         }
37         return;
38     }
39     for(int i=kind[t-1]+1;i<=maxnum+1;i++)
40     {
41         kind[t]=i;
42         int _maxnum=dp(t);
43         dfs(t+1,_maxnum);
44     }
45 }
46 
47 int main()
48 {
49     scanf("%d%d",&n,&k);
50     dfs(1,0);
51     printf("%d",res[1]);
52     for(int i=2;i<=k;i++)
53         printf(" %d",res[i]);
54     printf("\nMAX=%d\n",maxx);
55     return 0;
56 }
View Code

dp+dfs

解释: dfs(t,maxnum) 表示搜索到了第 t 张面值选择,而前 t+1 张能够最多连续取值 1~maxnum 

 dp(t) 返回在某次搜索中,此时 t 张面值能够最多连续取值的最大值

面值是递增存放的

思路:

dp:状态转移: f[x]=min(f[x],f[x-kind[i]]+1) 其中f数组中存储的是在这次搜索中,t张面值的纸币来取到x最小需要几张

在每次一点点将每张面值加进去的时候(即17行dp函数外层循环),由于x(在这张面值加入进去能够取到的数)最小为这张面值,最大为 kind[t]*n (即最大面值有最大张数时),所以内层循环的边界是这样写的

dfs比较清楚

最近不是很想干正事~昨天不然应该写完的,但是后来还是打了一晚上游戏(*?ω-q) 

所以虽然难度标的是普及,但当时根本没心思写所以感觉超难……

18.04.09 luoguP1021 邮票面值设计

标签:void   include   情况   允许   输入输出   range   class   最大   copy   

原文地址:https://www.cnblogs.com/yalphait/p/8761824.html

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