NOIP2011 day1 选择客栈

动态规划,设f[i,j]为前i个客栈中色调为j的可行方案,s[i,j]为前i个客栈中可以与之后色调为j的客栈搭配的客栈数,即有s[i,j]个客栈的色调为j,且该客栈与第i个客栈之间有符合条件的咖啡店,v[i]为第i个客栈的最低消费,c[i]为第i个客栈的色调a[i,j]为前i个客栈中色调为j的客栈的数目,则有:

if v[i]<=p then s[i,j]:=a[i,j] else s[i,j]:=s[i-1,j];

if c[i]<>j then f[i,j]:=f[i-1,j] else f[i,j]:=f[i-1,j]+s[i,j];

时间复杂度为O(nk),但是会超空间,所以还要用滚动数组,而且可以边读入边操作,这样就不需要用v和c这两个数组,只需两个变量即可,这样a,s,f这三个数组都变成一维的了,空间复杂度为O(3*k)

program hotel;
var
  n,m,p,i,j,ans,v,c:longint;
  a,s,f:array[0..50] of longint;
begin
  assign(input,'hotel.in');
  reset(input);
  assign(output,'hotel.out');
  rewrite(output);
  fillchar(f,sizeof(f),0);
  fillchar(v,sizeof(v),0);
  fillchar(c,sizeof(c),0);
  readln(n,m,p);
  for i:=1 to n do
  begin
    readln(c,v);
    if v<=p then
    begin
      for j:=0 to m-1 do
        s[j]:=a[j];
    end;
    for j:=0 to m-1 do
      if c<>j then f[j]:=f[j]
        else f[j]:=f[j]+s[j];
    inc(a[c]);
    if v<=p then inc(s[c]);
  end;
  ans:=0;
  for j:=0 to m-1 do
    ans:=ans+f[j];
  writeln(ans);
  close(input);
  close(output);
end.

原文地址:https://www.cnblogs.com/stmq/p/2660469.html