在位元鎮一共有 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...