zoukankan      html  css  js  c++  java
  • Uva 242 邮票和信封

    题目链接:https://vjudge.net/contest/146179#problem/D

    题意:

    信封上最多贴S张邮票。有N个邮票集合,每个集合有不同的面值。问哪个集合的最大连续邮资最大,输出最大连续邮资和集合元素。最大连续邮资是用S张以内邮票面值凑1,2,3...到n+1凑不出来了,最大连续邮资就是n。如果不止一个集合结果相同,输出集合元素少的,如果仍相同,输出最大面值小的。

    这个题意,刘汝佳的书上输出刚好写反。

    分析:

    先看一组数据。求最大连续邮资,那我想用二分啊,看这个答案是不是符合的,其实,在求这个答案是不是符合的,会重复计算,还不如按顺序计算。

    这个从1开始算,算到某一个数,他的最少票数>s,就达到要求的了。那么这就是一个无穷背包问题了。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 25;
     6 int a[maxn][maxn];
     7 int s,n;
     8 int dp[1005];
     9 int ans[25];
    10 
    11 const int INF = 0x3f3f3f3f;
    12 
    13 int main()
    14 {
    15     while(scanf("%d",&s),s)
    16     {
    17         scanf("%d",&n);
    18         for(int i=0; i<n; i++)
    19         {
    20             scanf("%d",&a[i][0]);
    21             for(int j=1; j<=a[i][0]; j++)
    22                 scanf("%d",&a[i][j]);
    23 
    24             memset(dp,INF,sizeof(dp));
    25             dp[0] = 0;
    26             for(int j=1; j<1005; j++)
    27             {
    28                 for(int k=1; k<=a[i][0]&&j-a[i][k]>=0; k++)
    29                 {
    30                     dp[j] = min(dp[j],dp[j-a[i][k]]+1);
    31                 }
    32                 if(dp[j]>s)
    33                 {
    34                     ans[i] = j-1;
    35                     break;
    36                 }
    37             }
    38         }
    39 
    40         int anss = -1,cnt = 0;
    41         for(int i=0; i<n; i++)
    42         {
    43             if(ans[i]>anss)
    44             {
    45                 anss = ans[i];
    46                 cnt = i;
    47             }
    48             else if(ans[i]==anss&&a[i][0]<a[cnt][0]) cnt = i;   //票数最少
    49             else if(ans[i]==anss&&a[i][0]==a[cnt][0])
    50             {
    51                 bool ok = false;
    52                 for(int j=a[i][0]; j>=0; j--)
    53                 {
    54                     if(a[i][j]<a[cnt][j])
    55                     {
    56                         ok = true;
    57                         break;
    58                     }
    59                     else if(a[i][j]>a[cnt][j]) break;
    60                 }
    61                 if(ok) cnt = i;
    62             }
    63         }
    64         printf("max coverage =%4d :",anss);
    65         for(int i=1; i<=a[cnt][0]; i++)
    66             printf("%3d",a[cnt][i]);
    67         puts("");
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    Docker——搭建SFTP
    PicGo——利用PicGo和GitHub搭建免费图床提供给Typecho使用
    GitHub——如何生成Personal access tokens
    leetcode——两数相加【二】
    每天一道面试题——请实现add(1,2)(3)【二】
    leetcode——两数之和【一】
    每天一道面试题——JavaScript的this指向【一】
    PHP——安装ThinkPHP框架报错
    项目代码 if/else 过多,引起程序猿口吐莲花
    JDK9-JDK14 相关新特性说明及使用
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6240989.html
Copyright © 2011-2022 走看看