【动态规划】数字游戏(game)

【问题描述】

  小W发明了一个游戏,他在黑板上写出了一行数字a1,a2,…an,然后给你m个回合的机会,每回合你可以从中选择一个数擦去它,接着剩下来的每个数字ai都要递减一个值bi如此重复m个回合,所有你擦去的数字之和就是你所得到的分数。

    小W和他的好朋友小Y玩了这个游戏,可是他发现,对于每个给出的an和bn序列,小Y的得分总是比他高。小W很不服气,想让你帮他算算,对于每个an和bn序列,可以得到的最大得分是多少。这样他就知道有没有可能超过小Y的得分。

【输入文件】

    输入文件game.in的第1行,一个整数n(1≤n≤200),表示数字的个数。

    第2行,一个整数m(1≤m≤n),表示回合数。

    接下来一行有n个不超过10000的正整数,a1,a2,…an,表示原始数字

    最后一行有n个不超过500的正整数,b1,b2,…bn,表示每回合每个数字递减的值

【输出文件】

    一个整数,表示最大可能的得分。结果输出到文件game.out。

【样例输入】

3

3

10 20 30

4 5 6

【样例输出】

47

 


    这道题我曾经纠结于所谓“取数”的过程该怎么在方程中表示,也就是说,如何将“取了就不能再取”体现在方程中。后来才醒悟,如果这都能体现出来,那就真成搜索了。。囧rz。

    一般这种题,取数都是有顺序上的决策的,如果没有顺序,那就要创造一个顺序。比如这道题。。

题目大意:
    有n个数A[1]..A[n],你要从中取走m个数,你每取走一个数,剩下的每个数字都会被减去B[i],求能取走的最大数字和。

    如何使结果最优呢?首先,若我们取了A[i]和A[j],且B[i]<B[j],那我们一定是先取A[j]再取A[i],因为A[i]每回合损失较小。
    所以,我们取数时的顺序一定是先取递减值大的再取递减值小的,因此我们可以按B[i]数组从大到小排序,则取数的顺序一定是从前往后取。这样,取数的顺序就被找到了,不存在后效性。

    在排序以确定取数顺序之后,我们只需考虑要取哪些数。

解题思路:
    许多题目都是这样,我们需要先有序化,再开始动规。
    f[i,j]表示前i个数中取j个数所能获得的最大数字和
    f[i,0]=0
    f[i,1]=A[i]

状态转移:
    f[i,j]=max{f[i-1,j],f[i-1,j-1]+A[i]-B[i]*(j-1)}

程序代码:

var
  n,m,i,j,k:integer;
  a,b:array[1..200] of integer;
  f:array[0..200,0..200] of longint;

procedure qsort(l,r:integer);
var
  i,j,m,t:integer;
begin
  i:=l;
  j:=r;
  m:=b[(i+j)div 2];
  repeat
    while b[i]>m do inc(i);
    while b[j]<m do dec(j);
    if i<=j then begin
      t:=a[i];
      a[i]:=a[j];
      a[j]:=t;
      t:=b[i];
      b[i]:=b[j];
      b[j]:=t;
      inc(i);
      dec(j);
    end;
  until i>j;
  if l<j then qsort(l,j);
  if i<r then qsort(i,r);
end;

begin
  assign(input,'game.in');reset(input);
  assign(output,'game.out');rewrite(output);
  readln(n);
  readln(m);
  for i:=1 to n do read(a[i]);
  readln;
  for i:=1 to n do read(b[i]);
  qsort(1,n);
  for i:=1 to n do f[i,1]:=a[i];
  for i:=2 to n do
    for j:=1 to i do begin
      if f[i-1,j]>=f[i-1,j-1]+a[i]-b[i]*(j-1) then
        f[i,j]:=f[i-1,j]
      else
        f[i,j]:=f[i-1,j-1]+a[i]-b[i]*(j-1);
    end;
  writeln(f[n,m]);
  close(input);close(output);
end.
posted @ 2012-10-24 22:13  HowardZhang  阅读(1983)  评论(0编辑  收藏  举报