题面传送门

傻逼卡常屑题/bs/bs,大概现场过得人比较少的原因就是它比较卡常罢(Fog

首先对于这样的题我们很难直接维护,不过注意到这个 \(n=300\) 给得很灵性,\(k\) 比较小和 \(k\) 比较大时各有自己的优势。因此考虑进行数据分治,也就是我们设一个阈值 \(B\),那么对于 \(k\le B\) 的情况是相对来说比较容易的,就设一个 \(dp_{i,S}\) 表示考虑到第 \(i\) 个位置,过去 \(k\) 个位置选择/不选择的状态为 \(S\) 的美丽程度之和,转移就枚举下一个位置选/不选即可实现 \(\mathcal O(1)\) 转移,时间复杂度 \(n2^B\)。

对于 \(k>B\) 的情况,我们考虑将序列想象成一个 \(\lceil\dfrac{n}{k}\rceil\) 行 \(k\) 列的矩阵,第 \(i\) 行包含了 \([(i-1)k+1,ik]\) 位置上的值(如果超过了 \(n\) 就在后面补 \(0\)),那么本题的限制等价于不能同时选择矩阵中相邻的元素,并且对于所有 \(1\le i<\lceil\dfrac{n}{k}\rceil\),第 \(i\) 行最后一个元素和第 \(i+1\) 行第一个元素不能同时被选择,那么如果说之前 \(k\le B\) 的情况是按行状压,那么 \(k>B\) 的情况也就自然可以想到按列状压了,不过由于本题对于第一列与最后一列还有额外的限制,因此考虑首先枚举第一列选择/不选择的状态,然后记 \(dp_{i,S}\) 表示考虑到第 \(i\) 列,第 \(i\) 列选择/不选择的状态为 \(S\) 的所有方案的美丽程度之和,转移就枚举下一列的状态即可,时间复杂度 \(\mathcal O(n8^{n/B})\)。

考虑优化,首先如果直接按照上面的做法做那直接 T 飞——不论你 \(B\) 取啥值。不过注意到对于这一类状压 \(dp\),合法的状态数通常是比较少的,如果你手比较勤快打个表也能发现 \([0,2^k-1]\) 中不存在二进制下不存在两个相邻的 \(1\) 的数恰有 \(Fib_{k+2}\) 个,因此可以直接一遍将符合条件的数筛出来,那么复杂度就降到了 \(nFib_{B+2}\) 和 \(n·Fib_{n/B+2}^3\),不过还是过不去。注意到对于 \(k\) 比较小的暴力已经没啥优化的空间了,因此考虑优化 \(k\) 比较大的暴力,首先我们枚举下一列的状态时候答案的贡献可以预处理出来,这样 \(n·Fib_{n/B+2}^3\) 就降到了 \(k·Fib_{n/B+2}^3\),其次对于两个合法状态 \(j,k\),满足 \(j\&k=0\) 的 \((j,k)\) 数量是小于 \(Fib_{n/B+2}^2\) 的,大约是 \(Fib_{n/B+2}^2\) 的一半,因此考虑将这个东西进一步预处理出来,这样常数就可以小一半。

实测 \(B=25\) 时复杂度最优,\(k\le 25\) 部分复杂度大约是 \(300·3\times 10^5=9\times 10^7\),\(k>25\) 部分复杂度大概是 \(377·26·47321=4\times 10^8\),不过对于 \(n=300,k=25\) 和 \(n=300,k=26\),我的程序似乎都只跑了 1.5s?话说回来由于这题出题人没有把数据卡满,因此这样的复杂度可以通过此题。否则肯定直接 T 飞。

所以说,下次看到 \(200,300\) 这样的数据范围,不要再拘泥地想什么 \(n^3,n^2\log n\) 了,有时候数据分治/根号分治+状压 \(dp\) 也可以出到类似的数据范围。

最后我稍微说一句,赛场上我使用的 vector 预处理合法的状态然后直接 T 飞,\(n=300,k=25\) 的数据跑了 4s,事实上直接每组数据都 \(2^k\) 跑一遍也行。

所以以后别用 vector 了(光速逃

完整代码:(为什么这次要放完整代码呢?因为可以康到三个火车头粘在一起占据程序大部分空间的壮丽景象)

  1. #pragma GCC optimize(2)
  2. #pragma GCC optimize(3)
  3. #pragma GCC target("avx")
  4. #pragma GCC optimize("Ofast")
  5. #pragma GCC optimize("inline")
  6. #pragma GCC optimize("-fgcse")
  7. #pragma GCC optimize("-fgcse-lm")
  8. #pragma GCC optimize("-fipa-sra")
  9. #pragma GCC optimize("-ftree-pre")
  10. #pragma GCC optimize("-ftree-vrp")
  11. #pragma GCC optimize("-fpeephole2")
  12. #pragma GCC optimize("-ffast-math")
  13. #pragma GCC optimize("-fsched-spec")
  14. #pragma GCC optimize("unroll-loops")
  15. #pragma GCC optimize("-falign-jumps")
  16. #pragma GCC optimize("-falign-loops")
  17. #pragma GCC optimize("-falign-labels")
  18. #pragma GCC optimize("-fdevirtualize")
  19. #pragma GCC optimize("-fcaller-saves")
  20. #pragma GCC optimize("-fcrossjumping")
  21. #pragma GCC optimize("-fthread-jumps")
  22. #pragma GCC optimize("-funroll-loops")
  23. #pragma GCC optimize("-fwhole-program")
  24. #pragma GCC optimize("-freorder-blocks")
  25. #pragma GCC optimize("-fschedule-insns")
  26. #pragma GCC optimize("inline-functions")
  27. #pragma GCC optimize("-ftree-tail-merge")
  28. #pragma GCC optimize("-fschedule-insns2")
  29. #pragma GCC optimize("-fstrict-aliasing")
  30. #pragma GCC optimize("-fstrict-overflow")
  31. #pragma GCC optimize("-falign-functions")
  32. #pragma GCC optimize("-fcse-skip-blocks")
  33. #pragma GCC optimize("-fcse-follow-jumps")
  34. #pragma GCC optimize("-fsched-interblock")
  35. #pragma GCC optimize("-fpartial-inlining")
  36. #pragma GCC optimize("no-stack-protector")
  37. #pragma GCC optimize("-freorder-functions")
  38. #pragma GCC optimize("-findirect-inlining")
  39. #pragma GCC optimize("-frerun-cse-after-loop")
  40. #pragma GCC optimize("inline-small-functions")
  41. #pragma GCC optimize("-finline-small-functions")
  42. #pragma GCC optimize("-ftree-switch-conversion")
  43. #pragma GCC optimize("-foptimize-sibling-calls")
  44. #pragma GCC optimize("-fexpensive-optimizations")
  45. #pragma GCC optimize("-funsafe-loop-optimizations")
  46. #pragma GCC optimize("-fdelete-null-pointer-checks")
  47. #pragma GCC optimize(2)
  48. #pragma GCC optimize(3)
  49. #pragma GCC target("avx")
  50. #pragma GCC optimize("Ofast")
  51. #pragma GCC optimize("inline")
  52. #pragma GCC optimize("-fgcse")
  53. #pragma GCC optimize("-fgcse-lm")
  54. #pragma GCC optimize("-fipa-sra")
  55. #pragma GCC optimize("-ftree-pre")
  56. #pragma GCC optimize("-ftree-vrp")
  57. #pragma GCC optimize("-fpeephole2")
  58. #pragma GCC optimize("-ffast-math")
  59. #pragma GCC optimize("-fsched-spec")
  60. #pragma GCC optimize("unroll-loops")
  61. #pragma GCC optimize("-falign-jumps")
  62. #pragma GCC optimize("-falign-loops")
  63. #pragma GCC optimize("-falign-labels")
  64. #pragma GCC optimize("-fdevirtualize")
  65. #pragma GCC optimize("-fcaller-saves")
  66. #pragma GCC optimize("-fcrossjumping")
  67. #pragma GCC optimize("-fthread-jumps")
  68. #pragma GCC optimize("-funroll-loops")
  69. #pragma GCC optimize("-fwhole-program")
  70. #pragma GCC optimize("-freorder-blocks")
  71. #pragma GCC optimize("-fschedule-insns")
  72. #pragma GCC optimize("inline-functions")
  73. #pragma GCC optimize("-ftree-tail-merge")
  74. #pragma GCC optimize("-fschedule-insns2")
  75. #pragma GCC optimize("-fstrict-aliasing")
  76. #pragma GCC optimize("-fstrict-overflow")
  77. #pragma GCC optimize("-falign-functions")
  78. #pragma GCC optimize("-fcse-skip-blocks")
  79. #pragma GCC optimize("-fcse-follow-jumps")
  80. #pragma GCC optimize("-fsched-interblock")
  81. #pragma GCC optimize("-fpartial-inlining")
  82. #pragma GCC optimize("no-stack-protector")
  83. #pragma GCC optimize("-freorder-functions")
  84. #pragma GCC optimize("-findirect-inlining")
  85. #pragma GCC optimize("-frerun-cse-after-loop")
  86. #pragma GCC optimize("inline-small-functions")
  87. #pragma GCC optimize("-finline-small-functions")
  88. #pragma GCC optimize("-ftree-switch-conversion")
  89. #pragma GCC optimize("-foptimize-sibling-calls")
  90. #pragma GCC optimize("-fexpensive-optimizations")
  91. #pragma GCC optimize("-funsafe-loop-optimizations")
  92. #pragma GCC optimize("-fdelete-null-pointer-checks")
  93. #pragma GCC optimize(2)
  94. #pragma GCC optimize(3)
  95. #pragma GCC target("avx")
  96. #pragma GCC optimize("Ofast")
  97. #pragma GCC optimize("inline")
  98. #pragma GCC optimize("-fgcse")
  99. #pragma GCC optimize("-fgcse-lm")
  100. #pragma GCC optimize("-fipa-sra")
  101. #pragma GCC optimize("-ftree-pre")
  102. #pragma GCC optimize("-ftree-vrp")
  103. #pragma GCC optimize("-fpeephole2")
  104. #pragma GCC optimize("-ffast-math")
  105. #pragma GCC optimize("-fsched-spec")
  106. #pragma GCC optimize("unroll-loops")
  107. #pragma GCC optimize("-falign-jumps")
  108. #pragma GCC optimize("-falign-loops")
  109. #pragma GCC optimize("-falign-labels")
  110. #pragma GCC optimize("-fdevirtualize")
  111. #pragma GCC optimize("-fcaller-saves")
  112. #pragma GCC optimize("-fcrossjumping")
  113. #pragma GCC optimize("-fthread-jumps")
  114. #pragma GCC optimize("-funroll-loops")
  115. #pragma GCC optimize("-fwhole-program")
  116. #pragma GCC optimize("-freorder-blocks")
  117. #pragma GCC optimize("-fschedule-insns")
  118. #pragma GCC optimize("inline-functions")
  119. #pragma GCC optimize("-ftree-tail-merge")
  120. #pragma GCC optimize("-fschedule-insns2")
  121. #pragma GCC optimize("-fstrict-aliasing")
  122. #pragma GCC optimize("-fstrict-overflow")
  123. #pragma GCC optimize("-falign-functions")
  124. #pragma GCC optimize("-fcse-skip-blocks")
  125. #pragma GCC optimize("-fcse-follow-jumps")
  126. #pragma GCC optimize("-fsched-interblock")
  127. #pragma GCC optimize("-fpartial-inlining")
  128. #pragma GCC optimize("no-stack-protector")
  129. #pragma GCC optimize("-freorder-functions")
  130. #pragma GCC optimize("-findirect-inlining")
  131. #pragma GCC optimize("-frerun-cse-after-loop")
  132. #pragma GCC optimize("inline-small-functions")
  133. #pragma GCC optimize("-finline-small-functions")
  134. #pragma GCC optimize("-ftree-switch-conversion")
  135. #pragma GCC optimize("-foptimize-sibling-calls")
  136. #pragma GCC optimize("-fexpensive-optimizations")
  137. #pragma GCC optimize("-funsafe-loop-optimizations")
  138. #pragma GCC optimize("-fdelete-null-pointer-checks")
  139. #pragma comment(linker,"/stack:200000000")
  140. #pragma GCC optimize("Ofast,no-stack-protector")
  141. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  142. #include <bits/stdc++.h>
  143. using namespace std;
  144. #define fi first
  145. #define se second
  146. #define fill0(a) memset(a,0,sizeof(a))
  147. #define fill1(a) memset(a,-1,sizeof(a))
  148. #define fillbig(a) memset(a,63,sizeof(a))
  149. #define pb push_back
  150. #define ppb pop_back
  151. #define mp make_pair
  152. #define y1 y1111111
  153. #define eprintf(...) fprintf(stderr,__VA_ARGS__)
  154. template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
  155. template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
  156. typedef pair<int,int> pii;
  157. typedef long long ll;
  158. typedef unsigned int u32;
  159. typedef unsigned long long u64;
  160. namespace fastio{
  161. #define FILE_SIZE 1<<23
  162. char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
  163. inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
  164. inline void putc(char x){(*p3++=x);}
  165. template<typename T> void read(T &x){
  166. x=0;char c=getchar();T neg=0;
  167. while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
  168. while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
  169. if(neg) x=(~x)+1;
  170. }
  171. template<typename T> void recursive_print(T x){return (!x)?void():(recursive_print(x/10),putc(x%10^48),void());}
  172. template<typename T> void print(T x){(!x)&&(putc('0'),0);(x<0)&&(putc('-'),x=~x+1);recursive_print(x);}
  173. template<typename T> void print(T x,char c){(!x)&&(putc('0'),0);(x<0)&&(putc('-'),x=~x+1);recursive_print(x);putc(c);}
  174. void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
  175. }
  176. const int MAXN=300;
  177. const int MOD=1e9+7;
  178. int n,k,w[MAXN+5];
  179. namespace sub1{
  180. const int MAX=3e5;
  181. int st[MAX+5],rid[(1<<25)+5],lim=0;
  182. int dp[2][MAX+5];
  183. void solve(){
  184. lim=0;
  185. for(int i=0;i<(1<<k);i++) (!(i&(i<<1)))?(st[++lim]=i,rid[i]=lim):rid[i]=0;
  186. for(int j=1;j<=lim;j++) dp[0][j]=dp[1][j]=0;
  187. dp[0][rid[0]]=1;int pre=0,nxt=1;
  188. for(int i=1;i<=n;i++){
  189. for(int j=1;j<=lim;j++) dp[nxt][j]=0;
  190. for(int j=1;j<=lim;j++) if(dp[pre][j]){
  191. int s=st[j],t=(s<<1)&((1<<k)-1);(dp[nxt][rid[t]]+=dp[pre][j])%=MOD;
  192. if((~s&1)&&(~s>>(k-1)&1)) (dp[nxt][rid[t|1]]+=1ll*dp[pre][j]*w[i]%MOD)%=MOD;
  193. } swap(pre,nxt);
  194. } int ans=0;for(int i=1;i<=lim;i++) (ans+=dp[pre][i])%=MOD;
  195. printf("%d\n",(ans-1+MOD)%MOD);
  196. }
  197. }
  198. namespace sub2{
  199. const int MAX=1e3;
  200. int st[MAX+5],rid[(1<<12)+5];
  201. int dp[MAXN+5][MAX+5],mul[MAXN+5][MAX+5],lim=0;
  202. int can[MAX+5][MAX+5];
  203. void solve(){
  204. int bt=n/k+1,ans=0;lim=0;
  205. for(int i=0;i<(1<<bt);i++) (!(i&(i<<1)))?(st[++lim]=i,rid[i]=lim):rid[i]=0;
  206. for(int i=1;i<=k;i++) for(int j=1;j<=lim;j++) mul[i][j]=0;
  207. for(int i=1;i<=k;i++) for(int j=1;j<=lim;j++){
  208. int s=st[j];
  209. if(n/k*k+i>n&&(s>>(bt-1)&1)) continue;
  210. mul[i][j]=1;
  211. for(int l=0;l<bt;l++) if(s>>l&1)
  212. mul[i][j]=1ll*mul[i][j]*w[l*k+i]%MOD;
  213. }
  214. for(int i=1;i<=lim;i++) can[i][0]=0;
  215. for(int i=1;i<=lim;i++) for(int j=1;j<=lim;j++)
  216. if(!(st[i]&st[j])) can[i][++can[i][0]]=j;
  217. for(int i=1;i<=lim;i++){
  218. // printf("%d\n",i);
  219. int s=st[i];
  220. if(n/k*k+k>n&&(s>>(bt-1)&1)) continue;
  221. for(int j=1;j<=k;j++) for(int l=1;l<=lim;l++) dp[j][l]=0;
  222. dp[k][i]=mul[k][i];
  223. for(int j=k;j>=2;j--) for(int l=1;l<=lim;l++) if(dp[j][l]){
  224. for(int o=1;o<=can[l][0];o++)
  225. (dp[j-1][can[l][o]]+=1ll*mul[j-1][can[l][o]]*dp[j][l]%MOD)%=MOD;
  226. } for(int l=1;l<=lim;l++) if(!(st[l]&(s<<1))) (ans+=dp[1][l])%=MOD;
  227. } printf("%d\n",(ans-1+MOD)%MOD);
  228. }
  229. }
  230. void solve(){
  231. scanf("%d%d",&n,&k);
  232. for(int i=1;i<=n;i++) scanf("%d",&w[i]);
  233. if(n<=100) (k<=15)?sub1::solve():sub2::solve();
  234. else (k<=25)?sub1::solve():sub2::solve();
  235. }
  236. int main(){
  237. int qu;scanf("%d",&qu);
  238. while(qu--) solve();
  239. return 0;
  240. }

HDU 6984 - Tree Planting(数据分治+状压 dp)的更多相关文章

  1. HDU 5067 Harry And Dig Machine(状压DP)(TSP问题)

    题目地址:pid=5067">HDU 5067 经典的TSP旅行商问题模型. 状压DP. 先分别预处理出来每两个石子堆的距离.然后将题目转化成10个城市每一个城市至少经过一次的最短时间 ...

  2. HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]

    题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...

  3. HDU 4917 Permutation(拓扑排序 + 状压DP + 组合数)

    题目链接 Permutation 题目大意:给出n,和m个关系,每个关系为ai必须排在bi的前面,求符合要求的n的全排列的个数. 数据规模为n <= 40,m <= 20. 直接状压DP空 ...

  4. HDU 1074:Doing Homework(状压DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Problem Description Ignatius has just ...

  5. hdu 2167 方格取数 【状压dp】(经典)

    <题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的  3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数 ...

  6. HDU 6149 Valley Numer II(状压DP)

    题目链接 HDU6149 百度之星复赛的题目……比赛的时候并没有做出来. 由于低点只有15个,所以我们可以考虑状压DP. 利用01背包的思想,依次考虑每个低点,然后枚举每个状态. 在每个状态里面任意枚 ...

  7. HDU 2809 God of War (状压DP)

    God of War Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU 4026 Unlock the Cell Phone 状压dp(类似TSP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4026 Unlock the Cell Phone Time Limit: 6000/3000 MS ...

  9. HDU 3681 Prison Break 越狱(状压DP,变形)

    题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...

随机推荐

  1. 【JAVA】【作业向】第一题:本学期一班级有n名学生,m门课程。现要求对每门课程的成绩进行统计:平均成绩、最高成绩、最低成绩,并统计考试成绩的分布律。

    1.预备知识:动态数组Array实现: 2.解题过程需要理解的知识:吧唧吧唧吧唧吧唧 不想做了 就用了最简单的方法 和c语言类似 java版本 `import java.util.Scanner; / ...

  2. 设置elementUI的table组件滚动条位置

    1.设置table的ref为tableList 2.设置滚动至顶部 this.$refs.tableList.bodyWrapper.scrollTop =0; 3.设置滚动至底部 this.$ref ...

  3. JavaScript之原型与原型链

    前言 ❝ JavaScript常被描述为一种「基于原型的语言」--每个对象都拥有一个「原型对象」,对象以其原型为模板.从原型继承属性和放法.原型对象也可能拥有原型,并从中继承属性和方法,一层一层以此类 ...

  4. Java只有值传递

    二哥,好久没更新面试官系列的文章了啊,真的是把我等着急了,所以特意过来催催.我最近一段时间在找工作,能从二哥的文章中学到一点就多一点信心啊! 说句实在话,离读者 trust you 发给我这段信息已经 ...

  5. Go语言核心36讲(Go语言进阶技术七)--学习笔记

    13 | 结构体及其方法的使用法门 我们都知道,结构体类型表示的是实实在在的数据结构.一个结构体类型可以包含若干个字段,每个字段通常都需要有确切的名字和类型. 前导内容:结构体类型基础知识 当然了,结 ...

  6. Sequence Model-week3编程题2-Trigger Word Detection

    1. Trigger Word Detection 我们的触发词将是 "Activate.".每当它听到你说 "Activate.",它就会发出 "c ...

  7. oo第三单元学习总结

    OO第三单元小结 一.JML语言理论基础及工具链梳理 在本单元我们学习了JML语言的一些基础知识,能够让我们看懂简单的JML规格并写出对应代码, 主要用到的知识点有:   1.requires 该子句 ...

  8. 鸿蒙轻内核M核的故障管家:Fault异常处理

    摘要:本文先简单介绍下Fault异常类型,向量表及其代码,异常处理C语言程序,然后详细分析下异常处理汇编函数实现代码. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十八 Fault异常处理& ...

  9. CF398A Cards | 贪心

    题目链接 我怎么连这种题都做得那么艰难-- 可以发现一些结论,然后枚举'x'被分成几段就好了. 我真的越来越菜 #include<iostream> #include<cstdio& ...

  10. ACL实验

    ACL实验 基本配置:略 首先根据题目策略的需求1,从这个角度看,我们需要做一条高级ACL,因为我们不仅要看你是谁,还要看你去干什么事情,用高级ACL来做的话,对于我们华为设备,只写拒绝,因为华为默认 ...