• NOIP模拟 6.30


    Problem 1 护花(flower.cpp/c/pas)

    【题目描述】

    约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小,约翰赶紧采取行动,把牛们送回牛棚. 牛们从1到N编号.第i只牛所在的位置距离牛棚Ti(1≤Ti≤2000000)分钟的路程,而在约翰开始送她回牛棚之前,她每分钟会啃食Di(1≤Di≤100)朵鲜花.无论多么努力,约翰一次只能送一只牛回棚.而运送第第i只牛事实上需要2Ti分钟,因为来回都需要时间.    写一个程序来决定约翰运送奶牛的顺序,使最终被吞食的花朵数量最小.

    【输入格式】

    1行输入N,之后N行每行输入两个整数TiDi

    【输出格式】

    一个整数,表示最小数量的花朵被吞食

    【样例输入】

    6

    3 1

    2 5

    2 3

    3 2

    4 1

    1 6

    【样例输出】

    86

    【样例解释】

     约翰用623415的顺序来运送他的奶牛

    按D/T排序,证明相邻的交换过来不会比原来更优即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <vector>
     7 #include <queue>
     8 inline void read(long long &x)
     9 {
    10     x = 0;char ch = getchar();char c = ch;
    11     while(ch > '9' || ch < '0')c = ch, ch = getchar();
    12     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar();
    13     if(c == '-')x = -x; 
    14 }
    15 const long long MAXN = 1000000 + 10;
    16 const int INF = 0x3f3f3f3f;
    17 
    18 long long n,T[MAXN],D[MAXN],cnt[MAXN];
    19 
    20 bool cmp(long long a, long long b)
    21 {
    22     return D[a] * T[b] > D[b] * T[a];
    23 }
    24 
    25 long long ans;
    26 long long sum;
    27 
    28 int main()
    29 {
    30     read(n);
    31     for(register long long i = 1;i <= n;++ i)
    32     {
    33         read(T[i]);read(D[i]);
    34         cnt[i] = i;
    35         sum += D[i];
    36     }
    37     std::sort(cnt + 1, cnt + 1 + n, cmp);
    38     for(register long long i = 1;i <= n;++ i)
    39     {
    40         sum -= D[cnt[i]];
    41         ans += ((long long)(sum * T[cnt[i]]) << 1);
    42     }
    43     printf("%lld", ans);
    44     return 0;
    45 }
    View Code

    Problem 2 修剪草坪(mowlawn.cpp/c/pas)

    【题目描述】

    在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪。现在,
    新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠。
    然而,FJ的草坪非常脏乱,因此,FJ只能够让他的奶牛来完成这项工作。FJ有N(1 <= N <= 100,000)只排成一排的奶牛,编号为1...N。每只奶牛的效率是不同的,奶牛i的效率为E_i(0 <= E_i <= 1,000,000,000)。靠近的奶牛们很熟悉,因此,如果FJ安排超过K1<=K<=N)只连续的奶牛,那么,这些奶牛就会罢工去开派对:)。因此,现在FJ需要你的帮助,计算FJ可以得到的最大效率,并且该方案中没有连续的超过K只奶牛。

    【输入格式】
    * 第一行:空格隔开的两个整数N和K
    * 第二到N+1行:第i+1行有一个整数E_i

    【输出格式】
    * 第一行:一个值,表示FJ可以得到的最大的效率值。

    【样例输入】

    5 2

    1

    2

    3

    4

    5

    输入解释:

    FJ有5只奶牛,他们的效率为1,2,3,4,5。他们希望选取效率总和最大的奶牛,但是

    他不能选取超过2只连续的奶牛

    【样例输出】

    12

    FJ可以选择出了第三只以外的其他奶牛,总的效率为1+2+4+5=12。

     神奇的dp。

    f[i]表示1..i只奶牛不选第i只的最小损耗

    初始状态f[0] = 0

    转移f[i] = min{f[j]} + e[i],其中(i - j - 1 <= k)

    维护一个单调递增队列,从队首取最小元素,新元素加到队尾并维持单调性,每次取队首元素时检查是否合法(即i - j - 1 <= k)

    此题开longlong,注意INF的取值,所以以后尽量手写一层,不要用INF

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <vector>
     7 #include <queue>
     8 inline void read(long long &x)
     9 {
    10     x = 0;char ch = getchar();char c = ch;
    11     while(ch > '9' || ch < '0')c = ch, ch = getchar();
    12     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar();
    13     if(c == '-')x = -x; 
    14 } 
    15 const long long INF = 0x3f3f3f3f3f3f3f3f;
    16 const int MAXN = 1000000 + 10;
    17 inline long long max(long a, long b){return a > b ? a : b;}
    18 inline long long min(long a, long b){return a < b ? a : b;}
    19 
    20 long long n,k,e[MAXN];
    21 long long ans;
    22 
    23 long long q1[MAXN << 1], q2[MAXN << 1],head, tail;
    24 long long f[MAXN]; 
    25 
    26 int main()
    27 {
    28     read(n);read(k);
    29     for(register long long i = 1;i <= n;++ i)
    30         read(e[i]),ans += e[i];
    31     
    32     head = tail = 1;//队列表示的范围:[head,tail] 
    33     q1[1] = q2[1] = 0;
    34     for(register int i = 1;i <= n;++ i)
    35     {
    36         while(i - q2[head] - 1 > k)head ++;
    37         f[i] = e[i] + q1[head];
    38         while(q1[tail] >= f[i] && head <= tail)tail--;
    39         q1[++ tail] = f[i];
    40         q2[tail] = i;
    41     }
    42     long long tmp = INF;
    43 //最好改为tmp = f[n - k];
    44     for(register int i = n - k;i <= n;++ i)
    45     {
    46         tmp = min(tmp, f[i]);
    47     }
    48     printf("%lld", ans - tmp);
    49     return 0;
    50 }
    View Code

    Problem 3 虫洞(wormhole.cpp/c/pas)

    【题目描述】

    John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有M条小路无向边连接着N (从1..N标号)块地,并有W个虫洞(有向边)。其中1<=N<=500,1<=M<=2500,1<=W<=200。 现在John想借助这些虫洞来回到过去(出发时刻之前),请你告诉他能办到吗。 John将向你提供F(1<=F<=5)个农场的地图。没有小路会耗费你超过10000秒的时间,当然也没有虫洞回帮你回到超过10000秒以前。

    【输入格式】

    * Line 1: 一个整数 F, 表示农场个数。

    * Line 1 of each farm: 三个整数 N, M, W。

    * Lines 2..M+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地中间有一条用时T秒的小路。

    * Lines M+2..M+W+1 of each farm: 三个数(S, E, T)。表示在标号为S的地与标号为E的地中间有一条可以使John到达T秒前的虫洞。

    【输出格式】

    * Lines 1..F: 如果John能在这个农场实现他的目标,输出"YES",否则输出"NO"。

    【样例输入】

    2

    3 3 1

    1 2 2

    1 3 4

    2 3 1

    3 1 3

    3 2 1

    1 2 3

    2 3 4

    3 1 8

    【样例输出】

    NO

    YES

    此虫洞非彼虫洞,明显简单一大截。

    SPFA找负环即可,题意描述不够明确。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <vector>
      7 #include <queue>
      8 inline void read(int &x)
      9 {
     10     x = 0;char ch = getchar();char c = ch;
     11     while(ch > '9' || ch < '0')c = ch, ch = getchar();
     12     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar();
     13     if(c == '-')x = -x; 
     14 } 
     15 inline int max(int a, int b){return a > b ? a : b;}
     16 inline int min(int a, int b){return a < b ? a : b;}
     17 inline void swap(int &a, int &b){int tmp = a;a = b;b = tmp;} 
     18 
     19 const int INF = 0x3f3f3f3f;
     20 const int MAXN = 5000 + 10;
     21 const int MAXE = 25000 + 10;
     22 const int MAXW = 2000 + 10;
     23 
     24 int t; 
     25 int n,m,w;
     26 
     27 struct Edge
     28 {
     29     int u,v,w,next;
     30 }edge[(MAXE << 1) + MAXW];
     31 int head[MAXN],cnt;
     32 
     33 inline void insert(int a, int b, int c)
     34 {
     35     edge[++cnt] = Edge{a,b,c,head[a]};
     36     head[a] = cnt;
     37 }
     38 
     39 std::queue<int> q;
     40 int b[MAXN], d[MAXN], cot[MAXN];
     41 
     42 inline int SPFA(int s)
     43 {
     44     memset(b, 0, sizeof(b));
     45     memset(d, 0x3f, sizeof(d));
     46     memset(cot, 0, sizeof(cot));
     47     q.push(s);
     48     d[s] = 0;
     49     b[s] = true;
     50     cot[s] ++;
     51     register int u,v;
     52     while(!q.empty())
     53     {
     54         u = q.front();
     55         q.pop();
     56         b[u] = false;
     57         for(register int pos = head[u];pos;pos = edge[pos].next)
     58         {
     59             v = edge[pos].v;
     60             if(d[v] > d[u] + edge[pos].w)
     61             {
     62                 d[v] = d[u] + edge[pos].w;
     63                 if(!b[v])
     64                 {
     65                     b[v] = true;
     66                     q.push(v);
     67                     cot[v] ++;
     68                     if(cot[v] >= n)return 0;
     69                 }
     70             }
     71         }
     72     }
     73     return 1;
     74 } 
     75 
     76 int main()
     77 {
     78     read(t);
     79     register int tmp1,tmp2,tmp3;
     80     for(;t;--t)
     81     {
     82         read(n);read(m);read(w);
     83         memset(edge, 0, sizeof(edge));
     84         memset(head, 0, sizeof(head));
     85         cnt = 0;
     86         for(register int i = 1;i <= m;++ i)
     87         {
     88             read(tmp1);read(tmp2);read(tmp3);
     89             insert(tmp1, tmp2, tmp3);
     90             insert(tmp2, tmp1, tmp3);
     91         }
     92         for(register int i = 1;i <= w;i ++)
     93         {
     94             read(tmp1);read(tmp2);read(tmp3);
     95             insert(tmp1, tmp2, -1 * tmp3);
     96         }
     97         if(!SPFA(1))
     98         {
     99             printf("YES
    ");
    100         }
    101         else
    102         {
    103             printf("NO
    ");
    104         }
    105     }
    106     return 0;
    107 }
    View Code

    T4暴力模拟没意思。。。不上了

  • 相关阅读:
    zencart_magiczoom
    如何把一个TXT文本文件按行数分割成多个文本文件
    工作时常用东西汇总
    asp Vernum
    sitemap制作
    php后门屌炸天
    威盾解密
    软路由
    企业安全工作要点
    内网ARP攻击
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7097711.html
Copyright © 2020-2023  润新知