Description
你曾经梦想过你是电脑游戏中的主角吗?这个故事的主角,Branimir,现在正在做这个梦。
在Branimir的梦中,世界是由从左到右排列的N座摩天大楼组成的。对于第i座摩天大楼,我们知道摩天大楼的高度Hi和房顶金币的数量Gi。游戏从在任何摩天大楼上跳跃开始,由几步组成。在每一步中,Branimir都可以从他目前所在的摩天大楼向右跳(他也有可能跳过其中的几个),到一个高度不低于现在的摩天大楼。假如Branimir在一座摩天大楼,他可以拿这座大楼的金币。Branimir可以在任意步数之后结束游戏(0步也可以)通往下一关,但必须要收集至少K个金币。
现在要求Branimir通往下一关的方案数。两个方案当做不同当且仅当Branimir在其中一次跳过其中一座摩天大楼而另一次没有。
Input
第一行包含两个整数n,K
接下来n行,每行两个整数Hi和Gi
Output
输出一个整数,表示不同的方案数。
Sample Input
input1:
4 6
2 1
6 3
7 2
5 6
input2:
2 7
4 6
3 5
input3:
4 15
5 5
5 12
6 10
2 1
Sample Output
output1:
3
output2:
0
output3:
4
Data Constraint
对于40%的数据,1<=n<=20
对于100%的数据,1<=n<=40,1<=k<=4*10^10,1<=Hi,Gi<=10^9
Hint
第一个样例解释
{1,2,3},{1,4}{4}三种方案
一道水题
出题人表示很无奈:怎么无数人O(2^n)水过?
以下是水法
var
h,g:array[1..40]of longint;
n,i,j,t:longint;
a:array[1..40,0..39]of longint;
k,s,e:int64;
u,v,b:array[1..40]of int64;
procedure js(x:longint;y:int64);
var
i:longint;
begin
if y>=k then begin inc(s,u[x]);exit;end;
if k>y+b[x]then exit;
for i:=1 to a[x,0]do js(a[x,i],y+g[a[x,i]]);
end;
begin
read(n,k);
for i:=1 to n do read(h[i],g[i]);
for i:=1 to n-1 do
for j:=i+1 to n do if h[j]>=h[i]then begin inc(a[i,0]);a[i,a[i,0]]:=j;inc(b[i],g[j]);end;
for i:=1 to n do
begin
fillchar(v,sizeof(v),0);
v[i]:=1;
for j:=i to n-1 do
for t:=1 to a[j,0]do inc(v[a[j,t]],v[j]);
for j:=i to n do inc(u[i],v[j]);
end;
j:=n;e:=g[j];
while(eand(j>0)do begin dec(j);inc(e,g[j]);end;
for i:=1 to j do js(i,g[i]);
write(s);
end.
上码被我手出数据卡成1300ms
如下
40 3072004656
1 30228272
2 169822132
3 974455406
4 64733775
5 90671933
6 348741409
7 793330484
8 201142109
9 111977576
10 243427852
11 399665796
12 995018323
13 721643216
14 841313640
15 707699547
16 529138916
17 519882352
18 881616002
19 498766088
20 865490675
21 232458666
22 597700394
23 411345945
24 387998118
25 734038648
26 88945902
27 735191481
28 30908815
29 769240618
30 545696192
31 305762748
32 619699431
33 498581770
34 290344941
35 882146149
36 1649071
37 890557019
38 430093690
39 857091340
40 970433163
答案:1099473411059
然而oj数据太水,于是优美地过了
这是正解