• [NOIP集训]10月18日


    今天的文件夹:10月18日.zip

    今天脑子转不起来,想不出来动规了。

    Orz @张翰文学神

    T1:快排,然后求连续数字的长度,简单判断即可。

    T2:


    题2、 养zsc(pig.pas/c/cpp)

    【题目描述】

        你有一个zsc圈,有$N$头zsc,每天你最多可以杀一头zsc卖钱,获益就是zsc的体重。但是每过一天每头zsc的体重都会下降$P_i$(当然,如果zsc体重$ leq 0$了,自然获利就是$0$),问$K$天内你的最大获利。

    【输人文件】

        第一行两个数$N,K$;

        第二行$N$个数表示zsc的初始重量$A_i$;

        第三行$N$个数表示$P_i$。

    【输出文件】

        一行一个数表示最大获利。

    【样例输入】

        2 2

        10 10

        1 2

    【样例输出】

    19

    【数据规模】

        对于20%的数据,满足$1 leq N leq 20$;

        对于100%的数据,满足$1 leq N leq 1000$,初始重量$ leq 10^5$。


    这道题属于DP中的一类,它的状态转移顺序并不是题目给出的,而是要自己构造。

    我们先证明一个定理:如果$P_i > P_j$,那么在其他顺序不变的情况下,先杀掉第$i$只zsc的解,不会比先杀第$j$只zsc的解差。

    证明:不妨设杀掉zsc的顺序为数组$ord$,其中$ord_k$表示杀掉的第$k$只zsc的原序号。设$ord_x=i$,$ord_y=j$,若$x>y$,那么此时杀掉这两只zsc的总收益为

    [max (0,A_i-(x-1)*P_i)+max (0,A_j-(y-1)*P_j)]

    而交换了顺序后(即$ord_x=j$,$ord_y=i$),总收益为

    [max (0,A_j-(x-1)*P_j)+max (0,A_i-(y-1)*P_i)]

    这里有多种情况,这里举例分析出现的数据都大于0的情况,若出现等于0或小于0,根据条件也可同样证明。

    假设都大于0,那么上述两式可以化简为

    [A_i+A_j-(x-1)*P_i-(y-1)*P_j]

    [A_i+A_j-(x-1)*P_j-(y-1)*P_i]

    又因为$x-1>y-1$,$P_i>P_j$,由排序不等式

    [(x-1)*P_i+(y-1)*P_j>(x-1)*P_j+(y-1)*P_i]

    进而有

    [A_i+A_j-(x-1)*P_i-(y-1)*P_j<A_i+A_j-(x-1)*P_j-(y-1)*P_i]

    于是得证。

    这样看来,在最后的最优解中,$P$数组必然是递减的。因此我们先对所有zsc按$P$值排序,这之后选出zsc来杀的顺序就是一定的,只要选出$K$只,求最优解。这就转化为了01背包模型。

    T3:


    3、zsc处理(rubbish.pas/c/cpp)

    【问题描述】

        聚会结束,留下许多zsc。Candy家里总共有$n$个zsc等待处理,每个zsc对于candy和飘飘乎居士处理的时间都是不同的,而且每个zsc只需要一个人处理。当然,candy和飘飘乎居士可以同时处理不同的zsc。记两人中耗费最长时间为最后总时间。candy希望能够尽快的处理完所有的zsc,因此,他想要知道处理完这些zsc最少需要耗费多少时间?

    【输入格式】

        第一行一个正整数$n$,表示一共有$n$个zsc需要处理

        接下来一个$2*n$的矩阵。

        矩阵第一行第$i$个数表示candy处理第$i$个zsc所需消耗的时间

        矩阵第二行第$i$个数表示飘飘乎居士处理第$i$个zsc所需消耗的时间

    【输出格式】

        一行,最后耗费的时间

    【输入样例】

        5

        2 4 1 4 5

        2 1 3 4 1

    【输出样例】

        5

    【样例说明】

        candy完成zsc 3与zsc 4的清理,耗时为5

        飘飘乎居士完成zsc 1 2 5的清理,耗时为4,由于candy耗费的时间较长,所以记candy耗费时间为最后总时间,所以最后答案为5。

    【数据规模】

        对于30%的数据 $0<n leq 30$

        对于100%的数据 $0<n leq 1000$,Candy和飘飘乎居士处理每个zsc的时间$ leq 10$,对任何一个人处理所有zsc时间总和$ leq 4000$


     一道DP杂题,思路到了就很水了。有的人看到"最大值最小"就去想什么二分答案、并查集等,其实这题是个DP。

    考虑数据范围,我们分别用$a_i,b_i$分别表示两人处理第$i$件zsc的用时,$ans[i][j]$表示处理前$i$个zsc,其中candy用时为$j$时,飘飘乎居士用的最短时间。状态转移方程为

    [ans[i][j]=min(ans[i-1][j]+b_i,ans[i-1][j-a_i])]

    其中的两种决策分别是让飘飘乎居士和candy来处理这一件zsc。当然,对于$j$小于$a_i$的情况,不考虑后一种情况即可。

    最后输出的是在所有$i$中,$i+ans[n][i]$的最小值。

    T4:容我再想两天。。。

    代码:

     1 program amblygonite;
     2 var
     3     a:array[1..1100000] of longint;
     4     n,i,j,k,m:longint;
     5 procedure qsort(l,r:longint);
     6 var
     7     i,j,x,y:longint;
     8 begin
     9     i:=l;
    10     j:=r;
    11     x:=a[(l+r) div 2];
    12     repeat
    13         while a[i]<x do
    14             inc(i);
    15         while x<a[j] do
    16             dec(j);
    17         if not(i>j) then
    18         begin
    19             y:=a[i];
    20             a[i]:=a[j];
    21             a[j]:=y;
    22             inc(i);
    23             dec(j);
    24         end;
    25     until i>j;
    26     if l<j then
    27         qsort(l,j);
    28     if i<r then
    29         qsort(i,r);
    30 end;
    31 begin
    32     assign(input,'amblygonite.in');
    33     reset(input);
    34     assign(output,'amblygonite.out');
    35     rewrite(output);
    36     readln(n);
    37     if n=0 then 
    38     begin 
    39         writeln(0); 
    40         close(input);
    41         close(output);
    42         halt; 
    43     end;
    44     for i:=1 to n do 
    45         read(a[i]);
    46     readln;
    47     qsort(1,n);
    48     j:=0;
    49     m:=0;
    50     while j<n do
    51     begin
    52         inc(j);
    53         k:=j;
    54         while (a[j+1]=a[j])and(j<n) do 
    55             inc(j);
    56         inc(m,(j-k+1) div 10);
    57     end;
    58     writeln(m);
    59     close(input);
    60     close(output);
    61 end.
    amblygonite.pas
     1 program pig;
     2 uses math;
     3 var
     4     a,p:array[1..1000] of longint;
     5     n,k:longint;
     6     ans:array[0..1000] of longint;
     7     i,j,ls:longint;
     8 begin
     9     assign(input,'pig.in');
    10     reset(input);
    11     assign(output,'pig.out');
    12     rewrite(output);
    13     readln(n,k);
    14     for i:=1 to n do
    15         read(a[i]);
    16     for i:=1 to n do
    17         read(p[i]);
    18     for i:=1 to n-1 do
    19         for j:=i+1 to n do
    20             if (p[i]<p[j])or((p[i]=p[j])and(a[i]<a[j])) then
    21             begin
    22                 ls:=a[i]; a[i]:=a[j]; a[j]:=ls;
    23                 ls:=p[i]; p[i]:=p[j]; p[j]:=ls;
    24             end;
    25     fillchar(ans,sizeof(ans),0);
    26     for i:=1 to n do
    27         for j:=k downto 1 do
    28             ans[j]:=max(ans[j],ans[j-1]+max(0,a[i]-(j-1)*p[i]));
    29     writeln(ans[k]);
    30     close(input);
    31     close(output);
    32 end.
    pig.pas
     1 program rubbish;
     2 uses math;
     3 var
     4     n:longint;
     5     a,b:array[1..1000] of longint;
     6     i,j,k:longint;
     7     ok:array[0..1000,0..4000] of longint;
     8     sum1,ans:longint;
     9 begin
    10     assign(input,'rubbish.in');
    11     reset(input);
    12     assign(output,'rubbish.out');
    13     rewrite(output);
    14     readln(n);
    15     sum1:=0;
    16     for i:=1 to n do
    17     begin
    18         read(a[i]);
    19         sum1:=sum1+a[i];
    20     end;
    21     for i:=1 to n do
    22         read(b[i]);
    23     fillchar(ok,sizeof(ok),$3f);
    24     ok[0,0]:=0;
    25     for i:=1 to n do
    26         ok[i,0]:=ok[i-1,0]+b[i];
    27     for i:=1 to n do
    28     begin
    29         for j:=0 to a[i]-1 do
    30             ok[i,j]:=ok[i-1,j]+b[i];
    31         for j:=a[i] to sum1 do
    32             ok[i,j]:=min(ok[i-1,j]+b[i],ok[i-1,j-a[i]]);
    33     end;
    34     ans:=$3f3f3f3f;
    35     for i:=1 to sum1 do
    36         ans:=min(ans,max(i,ok[n,i]));
    37     writeln(ans);
    38     close(input);
    39     close(output);
    40 end.
    rubbish.pas
  • 相关阅读:
    BZOJ3670:[NOI2014]动物园(KMP)
    415. [HAOI2009] 旅行
    U10223 Cx大帝远征埃及
    U10206 Cx的治疗
    2741. [济南集训 2017] 掰巧克力
    复习题目汇总 over
    7-20 表达式转换(25 分)
    7-19 求链式线性表的倒数第K项(20 分)(单链表定义与尾插法)
    7-18 银行业务队列简单模拟(25 分)
    7-17 汉诺塔的非递归实现(25 分)(有待改进)
  • 原文地址:https://www.cnblogs.com/changke/p/4889943.html
Copyright © 2020-2023  润新知