zoukankan      html  css  js  c++  java
  • codeforces B. Color the Fence 解题报告

    题目链接:http://codeforces.com/problemset/problem/349/B

    题目意思:给定v升的颜料和9个需要花费ad 升的颜料,花费ad 升的颜料意味着得到第d个数字,现在要求在所有的花费不超过v升的情况下,使得这些数字组合起来是最大的。

             一开始直接从最小花费的颜料着手,如果花费的颜料是相同的,就转到从d(也就是位数)最大贪心。这样测试9就开始卡住了。

             受到乌冬兄的指点迷津,终于有了思路,陆陆续续改了很多次,终于过了。以下摘自他的语录,白话文,大家请谅解:

          稳用颜料最少,最大的数字,先保证位数最长,然后再将剩余颜料从大数字开始贪心

          因为要数最大,所以根据“数”的比较顺序:
    1。比较位数
    2。从高位开始比较

         从数字比较的方法,推出贪心既思路

         由于本人悟性太低,下面是更详细的解说:

       1、先稳到用最小颜料既数字d,假设它价值为c
       2、先构造出s = v div c个d,求出剩余颜料r = v mod c
       3、从最高位扫描s,从大到小枚举可替换数字d' >= d,假设价值为c':若c'-c <= r,则替换当前位置的d为d', r -= c' - c
       4、最后得出替换后的s, s'即为所求
       注意:价值即一个数字要使用的颜料量

      

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 1e6 + 5;
     9 struct paint
    10 {  
    11     int index;    // 数字
    12     int num;      // 该数字所花费的颜料量
    13 } a[maxn], b[maxn];
    14 
    15 int s[maxn];   // 用于保存结果
    16 
    17 int cmp(paint a, paint b)
    18 {
    19     if (a.num != b.num)    // 先保证用的颜料量最少
    20         return a.num < b.num;
    21     return a.index > b.index;   // 再保证数字最大
    22 }
    23 
    24 int main()
    25 {
    26     int i, j, v, tmp, t1;
    27     while (scanf("%d", &v) != EOF)
    28     {
    29 //        freopen("in.txt", "r", stdin);
    30         for (i = 1; i <= 9; i++)
    31         {
    32             a[i].index = i;
    33             scanf("%d", &a[i].num);
    34             b[i].index = i;   //b用于保存未排序前的序列,以便下面从大数字开始枚举
    35             b[i].num = a[i].num;
    36         }
    37         sort(a+1, a+10, cmp);
    38         if (v < a[1].num)  // v比最少花费的颜料更少
    39             printf("-1
    ");
    40         else
    41         { 
    42             tmp = v / a[1].num;  // 得出最大位数
    43             if (v % a[1].num == 0) // 如果刚好可以除尽,最大的数就是tmp个a[1].num的数。
    44             {
    45                 for (i = 0; i < tmp; i++)
    46                     printf("%d", a[1].index);
    47                 printf("
    ");
    48             }
    49             else
    50             {
    51                 for (i = 0; i < tmp; i++)
    52                 {
    53                     s[i] = a[1].index;  // 先得出目前来说最长的数字,但可能不是最终结果
    54                 }
    55                 int r = v % a[1].num;   // 余数
    56                 t1 = r;
    57                 for (i = 0; i < tmp; i++)
    58                 {    
    59                     for (j = 9; j >= 1; j--) // 从最大的位数开始枚举
    60 { 61 if (b[j].num - a[1].num <= r && a[1].index < b[j].index) // 没有超过余数且数字比原来的排列数字的位数要大
    62 { 63 s[i] = b[j].index; 64 r = r - (b[j].num - a[1].num); // 余数要有所减少
    65 break; 66 } 67 } 68 } 69 if (t1 == r) // 如果根本没有可替换的数,那么就和刚好除尽的是同一种情况 70 { 71 for (i = 0; i < tmp; i++) 72 printf("%d", a[1].index); 73 printf(" "); 74 } 75 else 76 { 77 for (i = 0; i < tmp; i++) // 否则有替换的就输出新的最大数字
    78 { 79 printf("%d", s[i]); 80 } 81 printf(" "); 82 } 83 } 84 } 85 } 86 return 0; 87 }
  • 相关阅读:
    HTTP/HLS/RTMP超级负载测试工具(转)
    Jmeter监控Linux服务器性能
    装饰器做缓存
    内置装饰器
    Python装饰器 计时器记录方法执行性能
    【Python】装饰器实现日志记录
    Java对关于两个地点的根据经纬度算出后排序
    JS获得当前位置信息
    百度地图插件开发使用三 及jquery function(a.b)排序等
    css用clearfix清除浮动
  • 原文地址:https://www.cnblogs.com/windysai/p/3432414.html
Copyright © 2011-2022 走看看