首先感谢徐老师的慷慨,让蒟蒻有幸膜拜了学军的神题。祝NOI2015圆满成功

  同时膜拜碾压了蒟蒻的众神QAQ

填填填

  我的DP比较逗比……(当时看到其他大神有更加优秀的做法)

  f[i][j]表示前 i 个数,第一行填了 j 个的方案数,那么如果 i 并没有固定位置,f[i][j]=f[i-1][j]+f[i-1][j-1];即 i 这个数放在第一行或是第二行。。。(废话)

  如果 i 固定的位置是第一行(1,y),那么f[i]中只有f[i][y]=f[i-1][y-1];(这个数一定放在第一行)

  如果 i 固定的位置是第二行(2,y),那么f[i]中只有f[i][i-y]=f[i-1][i-y];(一定放在第二行)

  这个DP是会爆空间的,但是我们发现f[i]只跟f[i-1]有关,所以滚动数组优化一下就好了……(我一开始还在蛋疼高精度的数组开不下)

 

  我比较傻逼,不知道XJOI是不能用#ifndef ONLINE_JUDGE的,所以第一题没删文件操作……爆零滚粗了,删掉后是70分,两RE四TLE。

  然后开始了漫漫卡常之路……比如高精从int压9位改成long long压17位,高精加的过程用指针实现(Orz Davidlee1999)

  RE的那两个点是怎么回事呢?因为如果 i 固定的位置是第二行的时候,i-y可能会越界!(也就是无法得到一组合法解)那么这个时候我需要特判一下……

 1 //XJOI test7 A
 2 #include<ctime>
 3 #include<vector>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define rep(i,n) for(int i=0;i<n;++i)
10 #define F(i,j,n) for(int i=j;i<=n;++i)
11 #define D(i,j,n) for(int i=j;i>=n;--i)
12 #define pb push_back
13 using namespace std;
14 inline int getint(){
15     int v=0,sign=1; char ch=getchar();
16     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
17     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
18     return v*sign;
19 }
20 const int N=4010,INF=~0u>>2;
21 typedef long long LL;
22 /******************tamplate*********************/
23   
24 struct bint{
25     LL a[50],l;
26     bint(){l=0;memset(a,0,sizeof a);}
27     LL& operator [] (int x){return a[x];}
28 }f[2][N];
29 const LL Limit=100000000000000000LL;
30 void print(bint a){
31     printf("%lld",a[a.l]);
32     D(i,a.l-1,1) printf("%017lld",a[i]);
33     puts("");
34 }
35 bint operator + (bint a,bint &b){
36     LL *it1=a.a+1,*it2=b.a+1;
37     int l=max(a.l,b.l);
38     F(i,1,l){
39         *it1+=*it2;
40         it1++; it2++;
41     }
42     it1=a.a+1,it2=a.a+2;
43     F(i,1,l){
44         if (*it1>=Limit) *it1-=Limit,(*it2)++;
45         it1++; it2++;
46     }
47     if (a[l+1]>0) a.l=l+1; else a.l=l;
48     return a;
49 }
50 int n,v[3][N];
51 typedef pair<int,int> pii;
52 #define mp make_pair
53 #define fi first
54 #define se second
55 pii pos[N];
56   
57   
58 int main(){
59 //  time_t start,end; start=clock();
60     n=getint();
61     F(i,1,2) F(j,1,n){
62         v[i][j]=getint();
63         if (v[i][j]) pos[v[i][j]]=mp(i,j);
64     }
65     f[0][0].l=f[0][0][1]=1;
66     F(i,1,2*n){
67         int now=i&1;
68         if (pos[i].fi==1){
69             int j=pos[i].se;
70             f[now][j]=f[now^1][j-1];
71         }else if (pos[i].fi==2){
72             int j=i-pos[i].se;
73             if (j<=0){printf("0\n"); return 0;}
74             f[now][j]=f[now^1][j];
75         }else{
76             F(j,(i+1)/2,min(i,n)){
77                  f[now][j]=f[now^1][j-1]+f[now^1][j];
78 //                 f[now][j]=f[now][j]+f[now^1][j];
79             }
80         }
81         F(j,i/2,min(i-1,n)) f[now^1][j]=bint();
82     }
83     print(f[0][n]);
84 /*  end=clock();
85     cout <<"start : "<<start<<endl;
86     cout <<"end : "<<end<<endl;
87     cout <<"time : "<<double(end-start)/CLOCKS_PER_SEC<<endl;
88 */  return 0;
89 }
View Code

相关文章: