2018雅礼 折射

Posted starsing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018雅礼 折射相关的知识,希望对你有一定的参考价值。

  雅礼题好难啊。 

  这个DP题思路好强。

  

技术图片

  这个东西首先一眼就知道按y排的DP怎么写,大概就是设$f(i,j,k)$表示考虑到y坐标从大到小排名为i的点,这线上一次转是j,上上次转是k的数量,直接二维限制转移就行了。

  考虑这东西怎么优化。

  前缀和能搞时间,woc空间也被卡了???

  打出来表看一看????

  这个DP数组有好多都是空的。。。

  因为越往后x限制的越少。

  然后我就不会了。

  正经:设$f(i,0/1)$表示从x坐标排名为i,出门左转还是右转的线的数量。

  我一开始就否掉了这东西因为好像转移顺序会出问题。

  但是仔细考虑一下。

  对于一个点i,如果它的左侧有一个点j比他低,那么j能把自己的右转数量转移给i的左转数量。

  如果有一个点j比它高,那么应该是把i的左转转移给j的右转。

  但是这时i的左转不能转的比j还靠左否则不合题意。

  但是我们可以在转移i的时候先不转移i的右转,然后去枚举左侧j用i去给j做他的右转贡献(先后问题。有人会给i做贡献)。

  当我们从大到小枚举比i高的j的时候恰好就有,此时加到的i左转没有比j还小的点的贡献。

  那么就可以给j做右转贡献。

  所以它很对。

  还很快。

  还很省空间。

  

技术图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int N=6020,mod=1e9+7;
 7 int f[N][N];
 8 inline int rd()
 9 
10     int s=0,w=1;
11     char cc=getchar();
12     for(;cc<0||cc>9;cc=getchar()) if(cc==-) w=-1;
13     for(;cc>=0&&cc<=9;cc=getchar()) s=(s<<3)+(s<<1)+cc-0;
14     return s*w;
15 
16 struct nodeint x,y;p[N];
17 bool cmp(node a,node b)return a.x<b.x;
18 int main()
19 
20     int n=rd();
21     for(int i=1;i<=n;i++)p[i].x=rd(),p[i].y=rd();
22     sort(p+1,p+n+1,cmp);
23     for(int i=1;i<=n;i++)
24     
25         f[i][0]=f[i][1]=1;
26         for(int j=n;j;j--)
27         
28             if(p[j].x>=p[i].x)continue;
29             if(p[j].y<p[i].y)f[i][0]=(f[i][0]+f[j][1])%mod;
30             else f[j][1]=(f[j][1]+f[i][0])%mod;
31         
32     
33     long long ans=0;
34     for(int i=1;i<=n;i++)
35         ans=((ans+f[i][0])%mod+f[i][1])%mod;
36     printf("%lld\n",(ans-n+mod)%mod);
37 
38 /*
39 g++ 1.cpp -o 1
40 ./1
41 4
42 2 2
43 3 1
44 1 4
45 4 3
46 */
View Code

 

以上是关于2018雅礼 折射的主要内容,如果未能解决你的问题,请参考以下文章

「雅礼集训2018」树

雅礼2018-03-11

雅礼2018-03-11 3

雅礼2018-03-11 2

[2018雅礼集训1-16]方阵

BSOJ 5445 -- 2018雅礼树 prufer序列 dp