先恭喜一下 vijos 升级成2,0 版本 恭喜恭喜。
描述
“妹妹背着洋娃娃,走到花园看樱花” – 我整个人都Hello kitty了。
好了,闲话就说到这里,已知:这是一个1×N的花园(虽然比较奇怪),被分成了N个格子,每个格子里有一种神奇的樱花(我也不知道为什么神奇,反正洋娃娃看着高兴),看到第i个格子上的花洋娃娃会得到不同的满足度Ci(每个花的满足度只被计算一次)。现在妹妹会背着洋娃娃从任意格子走进花园,当然从第i个格子进去会消耗Di个单位的满足度,然后游历花园,在一个格子向右走需要耗费R个单位的满足度,向左走需要耗费L个单位的满足度,最后从第i个格子出花园又要耗费Fi个单位的满足度。
接下来,我们需要设计一套游历方案,使得最终获得的总满足度最高(太低的话洋娃娃会……)格式
输入格式
第一行依次给出三个正整数N,L,R。
第二行有N个整数,第i个数为Di。
第三行有N个整数,第i个数为Fi。
第四行有N个整数,第i个数为Ci。输出格式
仅需要输出一行包括一个整数,表示最大获得的满足度为多少。
首先,这道题目是一道动规题,一开始呢,根本想不到怎么动规。 可能一看到动规的题目,我就想用一个二维数组f[i,j]来 表示 从第 i 个点到第j 个点的最大满意值,会想到f[i,j]与f[i,j-1], f[i,j+1], f[i+1,j],f[i-1,j] 有联系,好吧,只能说我还没弄清楚。
看到这道题的题解后,发现这里的dp不是直接dp f[i,j];
具体分析:
有 i,j 两点, 设起点为i 终点为 j,且i<j, 因为满意度只能计算一次,则从i走到j共有以下几种走法:
1.直接从i 走到j 。
2.从i向左走再走回i再走到j(说不定能多拿一点满意度)。
3.从i向右走到j再向右走再向左走回到j(理由同上)。
4. 2点和3点综合,从i点向左走再走回i,然后从i向右走到j再向右走再向左走回到j。(理由同上)。
如果直接算的话,会很麻烦,所以我们弄一个预处理:
弄一个数组q[i],表示由1 到i 的满意度总和(不计代价)。
两个数组:
一个z[i],表示 由i向左走再走回来能够多拿的满意度(计代价)。
一个y[i],与z[i]一样,只不过方向向右。
若 i 为起点 j 为终点
我们可以知道 如果 i>j 则 s[i,j]=q[i]-q[j-1]+y[i]+z[j]-(i-j)*l-d[i]-f[j]
如果i<j s[i,j]=q[j]-q[i-1]+y[j]+z[i]-(j-i)*r-d[i]-f[j]
我们不确定 y和z 是否能够加上去,如果他为负,我们我不能加,否则不是最优解。
判断的话就有点麻烦,所以我们可以这样:
若 z[i]or y[i]<0 就 把他赋值为0。
这样就算为负我们加上去 也没问题了。
程序:
program p1627aaa; type arr=array[0..1010]of longint; arrr=array[0..1010,0..1010]of longint; var i,j,k,l,m,n,r,maxx:longint; s:arrr; q,c,d,f,z,y:arr; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; begin maxx:=-maxlongint; read(n,l,r); for i:=1 to n do read(d[i]); for i:=1 to n do read(f[i]); for i:=1 to n do read(c[i]); for i:=1 to n do for j:=1 to n do s[i,j]:=-maxlongint; for i:=1 to n do q[i]:=q[i-1]+c[i]; for i:=1 to n do begin z[i]:=-maxlongint; y[i]:=-maxlongint; end; for i:=1 to n do begin for j:=1 to i do begin z[i]:=max(z[i],q[i]-q[j-1]-(i-j)*(l+r)-c[i]); end; if z[i]<0 then z[i]:=0; end; for i:=1 to n do begin for j:=n downto i do begin y[i]:=max(y[i],q[j]-q[i-1]-(j-i)*(l+r)-c[i]); end; if y[i]<0 then y[i]:=0; end; for i:=1 to n do for j:=1 to n do begin if i>j then s[i,j]:=q[i]-q[j-1]+y[i]+z[j]-(i-j)*l-d[i]-f[j] else s[i,j]:=q[j]-q[i-1]+y[j]+z[i]-(j-i)*r-d[i]-f[j]; if s[i,j]>maxx then maxx:=s[i,j]; end; write(maxx); end.