[考试反思]0114省选模拟7:迷离

[考试反思]0114省选模拟7:迷离

这次考得相对不错,但是没什么水准。

只不过记得T1这道原题而已。虽说我忘了怎么做,而且数据范围不一样。。。差不多是从头想的。

但是并没有AC,像个弱智一样,有两个细节写的完全不对还有80分运气也是真好。

[考试反思]0114省选模拟7:迷离

其实挂了不止两个细节。。。以为是原题于是上来就写20分钟写完,然后过一会出一个锅。。。

然后看T2,感觉$O(nk^2)$也许差不多?常数很大。。。但也不会别的。挺好想但是不是很好写。

于是乎强烈谴责cbx没素质暴力水题考后还不改正解的无脸行径

于是就开始写,写了一个半小时。

[考试反思]0114省选模拟7:迷离

看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 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-02-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-04
  • 2022-12-23
  • 2021-11-07
猜你喜欢
  • 2021-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案