jzoj100044.
题目描述
有四个长度为N的数组a,b,c,d,现在需要你选择n个数构成数组e,数组e满足
- a[i]<=e[i]<=b[i]
- 最大
输入
输入文件名为abcd.in。
输入文件共 N+1 行。
第 1 行包含1个正整数N。
第 i+1 行包含4个整数a[i],b[i],c[i],d[i]。
输出
输出文件名为abcd.out。
输出共1行,包含1个整数,表示所给出公式的最大值。输入数据保证一定有解。
样例
Sample1: 5 -1 1 2 5 -2 2 1 2 0 1 1 3 -2 -1 3 10 -2 2 3 9 Sample2: 10 1 10 1 7 -10 10 2 0 -10 10 2 2 -10 10 2 0 1 10 1 0 -10 10 2 0 10 10 2 0 1 10 1 0 -10 10 2 0 1 10 1 0 Sample3: 10 1 10 1 0 -10 10 2 2 -10 10 2 2 -10 10 2 2 1 10 1 0 -10 10 2 2 -10 10 2 2 1 10 1 0 -10 10 2 2 1 10 1 0
Sample1: 2 Sample2: 90 Sample3: -4
题解
设f[i,j]表示前i个数,e[i]*c[i]和为k时最大值。
由于当j太大或太小时,后面的e[i]无论如何都回不到0
所以我们设上下界。
l[i]=
r[i]=
则i必须在范围内。
在判断一下f[i,j]是否可行,则可以卡掉很多状态。
就这样了。
var
i,j,n:longint;
k:longint;
a,b,c:array[1..200]of longint;
d:array[1..200]of longint;
lr:array[0..200,1..2]of longint;
f:array[0..200,-50000..50000]of longint;
function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;
begin
readln(n);
for i:=1 to n do readln(a[i],b[i],c[i],d[i]);
for i:=-50000 to 50000 do f[0,i]:=-151587082;
for i:=n-1 downto 1 do
begin
lr[i,1]:=lr[i+1,1]-b[i+1]*c[i+1];
lr[i,2]:=lr[i+1,2]-a[i+1]*c[i+1];
for j:=lr[i,1] to lr[i,2] do f[i,j]:=-151587082;
end;
f[0,0]:=0;
for i:=0 to n-1 do
begin
for j:=lr[i,1] to lr[i,2] do
begin
if f[i,j]<-151587081 then continue;
for k:=a[i+1] to b[i+1] do f[i+1,j+k*c[i+1]]:=max(f[i+1,j+k*c[i+1]],f[i,j]+k*d[i+1]);
end;
end;
writeln(f[n,0]);
close(input);
close(output);
end.