zoukankan      html  css  js  c++  java
  • HDU 6011:Lotus and Characters(贪心)

    http://acm.hdu.edu.cn/showproblem.php?pid=6011

    题意:共有n种字符,每种字符有一个val和一个cnt,代表这个字符的价值和数量。可以制造的总价值是:第一个字符的权值*1+第二个字符的权值*2+第三个字符的权值*3+……。问最大的总价值可以是多少。

    思路:首先可以确定价值越大的是放在越后,因为后面的位权比较大。考虑到价值有负数,因为不确定负数是否要放上去,所以需要枚举这些负数。

    首先输入的时候记录价值为负的个数negnum。将价值从小到大排序,然后枚举1~negnum+1,用一个beg记录当前枚举哪种字符,还有tol记录当前种类的字符用了多少次了。如果当前种类的字符数用完了,就要将beg+1了,这样一直枚举下去,取最优。至于枚举到negnum+1的原因,是因为还要算一个负数都不取的情况会不会更优。计算的话可以通过等差数列求和公式(一个一个枚举怕超时,实际上看别人没超时)。至于在比赛时候WA的原因,因为粗心。。忘了只有枚举到的种类是beg的时候才要减去tol,其他不用。(比赛的时候所有都减去了tol,血崩)。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #include <iostream>
     6 using namespace std;
     7 #define N 1010
     8 #define M 200010
     9 #define INF 0x3f3f3f3f
    10 typedef long long LL;
    11 struct node {
    12     int val, cnt;
    13 } p[30];
    14 
    15 bool cmp(const node &a, const node &b) { return a.val < b.val; }
    16 
    17 LL cal(int val, int cnt, int now) { // 等差数列
    18     int n = cnt + now;
    19     LL ans = val * n + (n * (n - 1)) / 2 * val;
    20     ans -= val * now + (now * (now - 1)) / 2 * val;
    21     return ans;
    22 }
    23 
    24 int main() {
    25     int t;
    26     scanf("%d", &t);
    27     while(t--) {
    28         int n;
    29         scanf("%d", &n);
    30         int negnum = 0;
    31         for(int i = 1; i <= n; i++) {
    32             scanf("%d%d", &p[i].val, &p[i].cnt);
    33             if(p[i].val < 0) negnum += p[i].cnt;
    34         }
    35         sort(p + 1, p + 1 + n, cmp);
    36         LL ans = 0, tmp = 0; int now = 0;
    37         int beg = 1, tol = 0;
    38         for(int i = 1; i <= negnum + 1; i++) { // 因为要看所有正数的情况,所以需要+1
    39             now = 0; tmp = 0;
    40             for(int k = beg; k <= n; k++) {
    41                 if(k == beg) tmp += cal(p[k].val, p[k].cnt - tol, now);
    42                 else tmp += cal(p[k].val, p[k].cnt, now);
    43                 if(k == beg) now += p[k].cnt - tol;
    44                 else now += p[k].cnt;
    45             }
    46             if(ans < tmp) ans = tmp;
    47             tol++;
    48             if(tol == p[beg].cnt) { beg++; tol = 0; }
    49         }
    50         printf("%I64d
    ", ans);
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    多媒体(2):WAVE文件格式分析
    多媒体(1):MCI接口编程
    EM算法(4):EM算法证明
    EM算法(3):EM算法运用
    EM算法(2):GMM训练算法
    EM算法(1):K-means 算法
    Support Vector Machine (3) : 再谈泛化误差(Generalization Error)
    Support Vector Machine (2) : Sequential Minimal Optimization
    Neural Network学习(二)Universal approximator :前向神经网络
    Neural Network学习(一) 最早的感知机:Perceptron of Rosenblatt
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6338101.html
Copyright © 2011-2022 走看看