• 邮票面值设计


    给定一个信封,最多只允许粘贴N张邮票,计算在给定KN+K15)种邮票的情况下(假定所有的邮票数量都足够),如何设计邮票的面值,能得到最大值MAX,使在1MAX之间的每一个邮资值都能得到。

    例如,N=3K=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表示最大的面值。

    这是用搜索来解决选什么面值,用DP来解决是否能凑出要求的值来

    搜索的上下边界没有想到 a[x]:a[x-1]+1,a[x-1]*n+1

    因为搜索的顺序是从小到大,所以a[x-1]+1,又因为要求数要连续,所以如果n张都贴当前最大值的后一个一定要凑出来

    然后也不知道要怎么求出最大的能连续凑出的值来

    dp[i]表示凑出i这种面值所需要的最小的张数,如果>n,i-1就是最大的能被连续凑出的面值

    i要从小到大推进,j枚举就可以了 从1到k

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 const int maxn=1e4+7;
     5 const int INF=0x7f7f7f7f;
     6 int n,k,ans;
     7 int a[maxn],imax[maxn],dp[maxn];
     8 void pan(){
     9   int i=0;dp[0]=0;
    10   while(dp[i]<=n){
    11     dp[++i]=INF;
    12     for(int j=1;j<=k;j++){
    13       if(i<a[j]) continue;
    14       dp[i]=min(dp[i],dp[i-a[j]]+1);
    15     }
    16   }
    17   if(i-1>ans){
    18     ans=i-1;
    19     for(int j=1;j<=k;j++) {imax[j]=a[j];}
    20   }
    21 }
    22 void dfs(int x){
    23   if(x==k+1){
    24     pan();
    25     return;
    26   }
    27   for(int i=a[x-1]+1;i<=a[x-1]*n+1;i++){
    28     a[x]=i;dfs(x+1);
    29   }
    30 }
    31 int main(){
    32   cin>>n>>k;dfs(1);
    33   for(int i=1;i<=k;i++) cout<<imax[i]<<" "; cout<<endl;
    34   cout<<"MAX="<<ans<<endl;
    35   return 0;
    36 } 
  • 相关阅读:
    【轻松前端之旅】<a>元素妙用
    【轻松前端之旅】HTML的块元素、行内元素和空元素
    每周学算法/读英文/知识点心得分享 9.27
    Linux find 命令详解
    每周学算法/读英文/知识点心得分享 9.19
    Linux命令之nohup 和 重定向
    基于C-W节约算法的车辆路径规划问题的Java实现
    每周学算法/读英文/知识点心得分享 9.6
    每周学算法/读英文/知识点心得分享 8.11
    每周学算法/读英文/知识点心得分享 3.11
  • 原文地址:https://www.cnblogs.com/lcan/p/9787395.html
Copyright © 2020-2023  润新知