[考试反思]1013csp-s模拟测试71:徘徊
Posted hzoi-deepinc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[考试反思]1013csp-s模拟测试71:徘徊相关的知识,希望对你有一定的参考价值。
分差好大。。。但是从排名上看也许还可以接受?
不算太炸
但是这个还是算了吧。。。
其实状态不是很好。
T1不会,打的搜索,想到一个剪枝但是感觉没什么用,所以没打。
考后打上,85了。。。打上另一个就90了。。。
T3已经想到正解思路了,但是不完善
T2想到正解,但是没有证明它是树形,于是没有打。。。
又说不完,晚上又要考,改善状态。
T1:毛一琛
又是meet in miiddle。又没想到。
其实也就是双向搜索,然后hash_map查状态即可。
打的lower_bound,多了一个log。勉强过了。
1 #include<cstdio> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 vector<int>X[1025],Y[1025]; 6 int n,x[22],ans,y[1048577],r; 7 void sch1(int p,int w,int st){ 8 if(p-1==n>>1){if(w>=0)X[st].push_back(w);return;} 9 sch1(p+1,w-x[p],st|1<<p-1);sch1(p+1,w,st);sch1(p+1,w+x[p],st|1<<p-1); 10 } 11 void sch2(int p,int w,int st){ 12 if(p==n+1){if(w>=0)Y[st].push_back(w);return;} 13 sch2(p+1,w+x[p],st|1<<p-r);sch2(p+1,w,st);sch2(p+1,w-x[p],st|1<<p-r); 14 } 15 int main(){ 16 scanf("%d",&n); 17 for(int i=1;i<=n;++i)scanf("%d",&x[i]);r=(n>>1)+1; 18 sch1(1,0,0);sch2(r,0,0); 19 for(int i=0;i<1<<(n>>1);++i)sort(X[i].begin(),X[i].end()); 20 for(int i=0;i<1<<n-(n>>1);++i)sort(Y[i].begin(),Y[i].end()); 21 for(int i=0;i<1<<(n>>1);++i)for(int j=0;j<1<<n-(n>>1);++j) 22 for(int v=0;v<X[i].size();++v) 23 if(lower_bound(Y[j].begin(),Y[j].end(),X[i][v])!=Y[j].end()) 24 if(*(lower_bound(Y[j].begin(),Y[j].end(),X[i][v]))==X[i][v]) 25 y[i<<n-(n>>1)|j]=1; 26 for(int i=1;i<1<<n;++i)ans+=y[i];//,printf("%d ",y[i]); 27 printf("%d ",ans); 28 }
T2:毛二琛
首先这题puts("0")会爆零,所以所有情况都有解。
考虑每一个数移动的方向,那么其实就限制了q序列上某两个相差为1的值的相对位置。
这样的话就是SAO那道题简化到序列上了,dp[i][j]表示考虑到操作i,其相对位置是j,前缀和优化就完事了。
代码倒好说。想到就能写出来。
1 #include<cstdio> 2 #define mod 1000000007 3 inline int Mod(int p){return p>=mod?p-mod:p;} 4 int p[5005],np[5005],n,dir[5005],dp[5005][5005],sum[5005][5005];//dir=2先i后i-1 5 int main(){ 6 scanf("%d",&n); 7 for(int i=1;i<=n;++i)scanf("%d",&p[i]),p[i]++,np[p[i]]=i; 8 for(int i=1;i<=n;++i) 9 if(np[i]>i){dir[i]=2;for(int j=i+1;j<p[i];++j)dir[j]=1;} 10 else {dir[i]=1;for(int j=i-1;j>np[i];--j)dir[j]=2;} 11 dp[1][1]=sum[1][1]=1; 12 for(int i=2;i<=n-1;++i){ 13 if(dir[i]==2)for(int j=1;j<=i;++j)dp[i][j]=Mod(mod+sum[i-1][i-1]-sum[i-1][j-1]); 14 else for(int j=1;j<=i;++j)dp[i][j]=sum[i-1][j-1]; 15 for(int j=1;j<=i;++j)sum[i][j]=Mod(sum[i][j-1]+dp[i][j]); 16 }printf("%d ",sum[n-1][n-1]); 17 }
T3:毛三琛
二分答案,剪枝,及时跳出。
如果目前的x连目前最优答案都不到,continue。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,k,p,a[10005],ans=1000000000; 4 int Mod(int x){return x>=p?x-p:x;} 5 int chk(int w,int xx){ 6 int al=1,f=0; 7 for(int i=1;i<=n&&al<=k;++i){int x=Mod(xx+a[i]);if(x>w)return 0;if(f+x>w)al++,f=x;else f+=x;} 8 if(al<=k)return 1; 9 return 0; 10 } 11 int main(){ 12 scanf("%d%d%d",&n,&p,&k); 13 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 14 for(int i=0;i<p;++i){ 15 if(!chk(ans,i))continue; 16 register int l=0,r=ans; 17 while(l<r-1)if(chk(l+r>>1,i))r=l+r>>1;else l=(l+r>>1)+1; 18 ans=min(ans,chk(l,i)?l:r); 19 } 20 printf("%d ",ans); 21 }
以上是关于[考试反思]1013csp-s模拟测试71:徘徊的主要内容,如果未能解决你的问题,请参考以下文章