这次考得相对不错,但是没什么水准。
只不过记得T1这道原题而已。虽说我忘了怎么做,而且数据范围不一样。。。差不多是从头想的。
但是并没有AC,像个弱智一样,有两个细节写的完全不对还有80分运气也是真好。
其实挂了不止两个细节。。。以为是原题于是上来就写20分钟写完,然后过一会出一个锅。。。
然后看T2,感觉$O(nk^2)$也许差不多?常数很大。。。但也不会别的。挺好想但是不是很好写。
于是乎强烈谴责cbx没素质暴力水题考后还不改正解的无脸行径
于是就开始写,写了一个半小时。
看T3,绝对大神题啊除了skyh谁会做啊(%%%大神打表)。60分暴力乱弄一个不会证的结论过样例(啥?归纳??)
花了半个小时。还有一个小时。直接放弃T3正解,自知T2板子容易爆炸于是老老实实写个对拍。
暴力疯狂出锅,修好之后发现了正解的锅。修啊修半个小时之后就AC了。
其实是发挥的不错的一次考试。对拍也挺明智的。只不过T1不注重细节单求速度的问题也有所暴露。
今天考试时难得状态上线。。。所以考试结束后累的一匹。。。
顺及:
昨天清了清博客的动态,从32页删到了10页。顺便看了看我联赛前的动态。
我怎么那么颓啊!!!
也活该联赛爆炸。想想最近一段时间也颓的不轻,效率挺低的(虽说最近的确是又累又闷但这并不是合适的理由)
自我督促一下。现在我没有放松的资本。。。
尽量更紧张一些吧。。。
T1:翻转硬币
题意:n硬币正面朝上,每次对一个长为$a_i$的区间翻转(共$m$种$a$),最后要求$k$个特定位置反面朝上其余正面。问最少翻转次数
$n \le 10000,m\le 100,k\le 10$。
0811NOIP模拟测试17的T3《星空》。数据范围略有变化。
然而当时并没有写题解,所以现在再说一说。
区间异或不难想到做差分。于是每次是对相距$a$的点同时操作。最多有$2k$个位置需要操作。
做$2k$次$BFS$找到点对之间相互到达的最少次数,然后做一个状压$dp$。
考场上挂的两个细节:
1,要注意差分之后数列实际上用到了$n+1$位所以上限不要只开到$n$。
2,状压$dp$时每次选出的点对不能与当前状态有交集。
其中状压$dp$的部分可以用那种钦定最小点的思路,这样复杂度会低一些。
最终复杂度$O(2knm+4^kn)$
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,k,dt[11111],bp[22][22],sp[11111],p[22],pc,dp[1048577],q[66666],stp[111]; 4 int main(){ 5 scanf("%d%d%d",&n,&k,&m); 6 for(int i=1,x;i<=k;++i)scanf("%d",&x),sp[x]^=1,sp[x+1]^=1; 7 for(int i=1;i<=n+1;++i)if(sp[i])p[pc]=i,pc++; 8 for(int i=1;i<=m;++i)scanf("%d",&stp[i]); 9 for(int i=0,h,t;i<pc;++i){ 10 memset(dt,0x3f,sizeof dt);dt[p[i]]=0;q[h=t=1]=p[i]; 11 for(;h<=t;++h){ 12 for(int j=1;j<=m;++j){ 13 if(q[h]+stp[j]<=n+1&&dt[q[h]+stp[j]]>dt[q[h]]+1)dt[q[++t]=q[h]+stp[j]]=dt[q[h]]+1; 14 if(q[h]-stp[j]>0&&dt[q[h]-stp[j]]>dt[q[h]]+1)dt[q[++t]=q[h]-stp[j]]=dt[q[h]]+1; 15 } 16 }for(int j=0;j<pc;++j)bp[i][j]=dt[p[j]]; 17 } 18 memset(dp,0x3f,sizeof dp);dp[0]=0; 19 for(int s=0;s<(1<<pc)-1;++s){ 20 int fs; 21 for(int j=0;j<pc;++j)if(!(s&1<<j)){fs=j;break;} 22 for(int j=fs+1;j<pc;++j)if(!(s&1<<j))dp[s|1<<fs|1<<j]=min(dp[s|1<<fs|1<<j],dp[s]+bp[j][fs]); 23 } 24 printf("%d\n",dp[(1<<pc)-1]>6666666?-1:dp[(1<<pc)-1]); 25 }