2018.12.15【NOIP提高组】模拟B组 jzoj100044.

9 篇文章 0 订阅
7 篇文章 0 订阅

jzoj100044.

题目描述

有四个长度为N的数组a,b,c,d,现在需要你选择n个数构成数组e,数组e满足

  1. a[i]<=e[i]<=b[i]
  2. \sum_{i=1}^{n}c[i]*e[i]=0
  3. \sum_{i=1}^{n}d[i]*e[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]=\sum_{j=i+1}^{n}-b[j]

r[i]=\sum_{j=i+1}^{n}-a[j]

则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.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值