十連測 D2T2 market(二分 揹包)

2021-08-07 23:59:28 字數 3470 閱讀 7134

在位元鎮一共有 n 家商店,編號依次為 1 到 n。每家商店只會賣一種物品,其中第 i 家商店的物品

單價為 ci,價值為 vi,且該商店開張的時間為 ti。

byteasar 計畫進行 m 次購物,其中第 i 次購物的時間為 ti,預算為 mi。每次購物的時候, byteasar

會在每家商店購買最多一件物品,當然他也可以選擇什麼都不買。如果購物的時間早於商店開張的時間,

那麼顯然他無法在這家商店進行購物。

現在 byteasar 想知道,對於每個計畫,他最多能購入總價值多少的物品。請寫乙個程式,幫助

byteasar 合理安排購物計畫。

注意:每次所花金額不得超過預算,預算也不一定要花完,同時預算不能留給其它計畫使用。

input

第一行包含兩個正整數 n; m,表示商店的總數和計畫購物的次數。

接下來 n 行,每行三個正整數 ci; vi; ti,分別表示每家商店的單價、價值以及開張時間。

接下來 m 行,每行兩個正整數 ti; mi,分別表示每個購物計畫的時間和預算。

output

輸出 m 行,每行乙個整數,對於每個計畫輸出最大可能的價值和。

examples

market.in

5 2

5 5 4

1 3 1

3 4 3

6 2 2

4 3 2

3 8

5 9

market.out

10 12

第乙個計畫可以在商店 2,3,5 各購買一件物品,總花費為 1 + 3 + 4 = 8,總價值為 3 + 4 + 3 = 10。

第二個計畫可以在商店 1,2,3 各購買一件物品,總花費為 5 + 1 + 3 = 9,總價值為 5 + 3 + 4 = 12。

day 2

notes

對於 100% 的資料, 1 ≤ ti;ti ≤ n。

這裡寫**片

program df;

var i,j,n,m,x,y,z,k,t,l,r,mid,sum:longint;

a,b,c:array[0..300] of longint;

f:array[-1..300,-1..90000] of longint;

procedure

sq(l,r:longint);

var i,j,mm,dd:longint;

begin

i:=l; j:=r;

mm:=c[(l+r) div

2];repeat

while c[i]do inc(i);

while c[j]>mm do dec(j);

if i<=j then

begin

dd:=a[i]; a[i]:=a[j]; a[j]:=dd;

dd:=b[i]; b[i]:=b[j]; b[j]:=dd;

dd:=c[i]; c[i]:=c[j]; c[j]:=dd;

inc(i); dec(j);

end;

until i>j;

if lthen sq(l,j);

if ithen sq(i,r);

end;

function

check

(x:longint):longint;

var l,r,mid:longint;

begin

l:=0; r:=n;

while l1

dobegin

mid:=(l+r) div

2;if c[mid]<=x then l:=mid

else r:=mid;

end;

if c[r]<=x then

exit(r)

else

exit(l);

end;

function

min(x,y:longint):longint;

begin

if x>y then

exit(y)

else

exit(x);

end;

function

deal

(x,y:longint):longint;

var l,r,mid:longint;

begin

l:=0; r:=sum;

while l1

dobegin

mid:=(l+r) div

2;if f[x,mid]<=y then l:=mid

else r:=mid;

end;

if f[x,r]<=y then

exit(r)

else

exit(l);

end;

begin

assign(input,'market.in');

reset(input);

assign(output,'market.out');

rewrite(output);

readln(n,k);

for i:=1

to n do

begin

readln(a[i],b[i],c[i]);

sum:=sum+b[i];

end;

sq(1,n);

for i:=0

to n do

for j:=1

to sum do

f[i,j]:=maxlongint div

2-10;

for i:=1

to n do

for j:=1

to sum do

//f[i,j]為當前i個商店,價值為j的最小預算為多少

begin

if (jthen f[i,j]:=f[i-1,j]

else f[i,j]:=min(f[i-1,j],f[i-1,j-b[i]]+a[i]);

end; //揹包不解釋

for i:=1

to n do

for j:=sum-1

downto0do

f[i,j]:=min(f[i,j],f[i,j+1]); // 使答案具有單調性,能夠二分(讓答案前面的值都等於答案,答案後面的值都大於答案)

for i:=1

to k do

begin

readln(t,m);

x:=check(t);

if x=0

then writeln(0)

else

writeln(deal(x,m));

end;

close(input);

close(output);

end.

NOIp2016十連測第五場T2 walk 題解

傳送門 最近由於參加noi集訓,好久沒有更新部落格啦tot 正解要從第二種部分分思路想。這個思路為什麼是o n max w o n times max w o n max w 的?因為每次求森林最長鏈時其實真正有用的點 邊並不多,而演算法將大量時間花費在了無用點 孤立點 上。如果找有用邊時順便記錄有...

校內測 11 27 T2 數字遊戲 二分

傳送門 一共有n nn個數,已知有k kk對數的和為正數 問最多有多少對數的乘積為正數 因為要使得積為正數的對數盡可能的多,所以我們原本的數應該都是些非零的數 這樣我們設有x xx個正數,就會有n x n xn x個負數 此時積為正數的對數為x x 1 2 n x n x 1 2 frac frac...

問題 D 二分遞迴快排(Qsort) 2

二分遞迴快排 qsort 用二分遞迴的方法實現快排 輸入 第一行乙個資料n,表示有n個數要排序。接下來n行每行乙個 10 7的整數。輸出 n行,由小到大排序後的資料 資料規模 n 10 5 思考 兩個遞迴都會被執行嗎?有幾種可能?includeusing namespace std int part...