嗯这道题我的做法是典型的用空间换时间
用a[i][j]记录颜色为i的客栈出现的坐标,每次枚举当前客栈到前一个同颜色的客栈间是否有符合条件的客栈,如果有,就是当前客栈之前出现的所有同色客栈数量,如果没有,就是上一个同色客栈的答案数,最后从头到尾遍历一遍每个客栈的答案累加,输出,结束
但是就在我写这篇博客的时候,我突然意识到,对于a数组,当当前节点为j时,我最多只用到了同色的客栈数以及a[i][j-1],那不就可以优化一维只记录上次同色客栈的答案数么???????那不就不用用空间换时间了?????
md我真是个智障。。
附上我无脑开的不知道浪费了多少空间的代码。。。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<queue>
6 #include<stack>
7 #include<deque>
8 #include<algorithm>
9 #define ll long long
10 using namespace std;
11 const ll oo=0x3f3f3f3f;
12 const ll N=200005;
13 const ll M=55;
14
15 ll n,k,p,sum;
16 ll ans[N],a[M][N],b[N];
17
18 ll Min(ll a,ll b){return a<b?a:b;}
19 ll Max(ll a,ll b){return a>b?a:b;}
20 ll Abs(ll a){return a>0?a:-a;}
21
22 ll get(){
23 char zy=getchar();
24 ll z=1,y=0;
25 while(zy>'9'||zy<'0'){
26 if(zy=='-') z=-1;
27 zy=getchar();
28 }
29 while(zy>='0'&&zy<='9'){
30 y=(y<<1)+(y<<3)+zy-'0';
31 zy=getchar();
32 }
33 return z*y;
34 }
35
36 int main(){
37 //freopen("P1311选择客栈.in","r",stdin);
38 //freopen("P1311选择客栈.out","w",stdout);
39 n=get();k=get();p=get();
40 for(ll i=1;i<=n;i++){
41 bool ok=false;
42 ll c=get();b[i]=get();
43 if(a[c][0]){
44 for(ll j=a[c][a[c][0]];j<=i;j++){
45 if(b[j]<=p){
46 ok=true;
47 break;
48 }
49 }
50 if(ok) ans[i]=a[c][0];
51 else ans[i]=ans[a[c][a[c][0]]];
52 }
53 a[c][++a[c][0]]=i;
54 }
55 for(ll i=1;i<=n;i++) sum+=ans[i];
56 printf("%lld\n",sum);
57 return 0;
58 }