zoukankan      html  css  js  c++  java
  • 数字游戏

    题意

    小W发明了一个游戏,他在黑板上写出了一行数字a1,a2,a3,……,an,然后给你M个回合的机会,每会回你可以从中选择一个数字擦去它,接着剩下来的每个数字ai都要递减一个值bi。如此重复m个回合,所有你擦去的数字之和就是你所得的分数。小W和他的好朋友小Y玩了这个游戏,可是他发现,对于每个给出的a和b序列,小Y的得分总比他高,所以他就很不服气。于是他想让你帮他算算,对于每个a和b序列,可以得到的最大得分是多少。


    分析

    我们知道,擦走的数字是有顺序的。如果可以规定一个序,删除的顺序必需和这个序相对应,就可以应用动态规划了。

    设F[i,j]表示从前i个删除j个数的最大分值。

    f[i,j]:=max{f[i-1,f[i-1,j-1]+a[i]-b[i]*(i-1)}




    var
    a,b:array[0..2001]of longint;
    n,m,i,j:longint;
    f:array[0..2001,0..2001]of longint;
    procedure kp(l,r:longint);
    var
    i,j,mid:longint;
    begin
        if l>r then exit;
        i:=l;j:=r;mid:=b[(l+r) div 2];
        repeat
             while b[i]>mid do inc(i);
             while b[j]<mid do dec(j);
             if i<=j then
             begin
                 b[0]:=b[i];b[i]:=b[j];b[j]:=b[0];
                 a[0]:=a[i];a[i]:=a[j];a[j]:=a[0];
                 inc(i);dec(j);
             end;
        until i>j;
        kp(l,j);
        kp(i,r);
    end;


    begin
        readln(n);readln(m);
        for i:=1 to n do
        read(a[i]);
        readln;
        for i:=1 to n do
        read(b[i]);
        kp(1,n);
        fillchar(f,sizeof(f),200);
        for i:=1 to n do
        begin
            f[i-1,0]:=0;
            for j:=1 to m do
            if f[i-1,j]<f[i-1,j-1]+a[i]-b[i]*(j-1) then f[i,j]:=f[i-1,j-1]+a[i]-b[i]*(j-1) else f[i,j]:=f[i-1,j];
        end;
        write(f[n,m]);
    end.

  • 相关阅读:
    Linux curl使用简单介绍
    SecureCRT编码转换vim
    BigTable/HBase基本概念解读 & Hbase shell常用命令
    Crontab用法说明(Linux)
    Sina SSO 登陆过程分析
    浅谈队列
    搞怪的 log4net 记录日志 性能测试
    iBatis.Net异步多线程 操作Ibatis报错
    高并发高负载的大型网站系统架构
    [置顶] IIs Web 站点安全 监控 站点自动部署 重启
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/9500159.html
Copyright © 2011-2022 走看看