[TOC]
#20161027考试
#####考试时间 7:50 AM to 11:15 AM


题目

考试包


据说这是一套比较正常的考卷,,,嗯,,或许吧,



而且,,整个小组其他人的分数加起来也不如apt123大神多,,

最终,3道题一共30分滚粗

T1:

树形dp题目,感觉我这种dp渣渣是想不出方程了,,%%%%一下apt大神,,

正解:

设dp[i][j]表示根节点为i,距离i最近的被选点的距离大于等于j时的最大节点数,dp[i][0]即为答案

转移:

设f[i][0] = a[i],表示选了a[i]后的初始状态,转移方程为:

dp[i][j] = max(dp[i][j] + dp[son[i]][max(k - j, j - i)], dp[i][max(k - j + 1, j)] + dp[son[i]][j - 1]); j = 1 -> k

dp[i][j] = max(dp[i][j], dp[i][j+1]);

考虑方程,显然设置状态时并没有考虑到同一个根的不同儿子之间的冲突情况,所以必须在转移时候加以限制。

  • 当j的值足够大时,该根节点的j层儿子之间一定不会发生矛盾,因此可以由dp[son[i]][j-1]向dp[i][j]转移

  • 当j的值比较小时,同层的子节点会发生冲突,那么就必须手动解决冲突,即将其中一个点设为k-j,以保证两个子节点之间的距离大于k

再考虑dp方程本身的含义,显然可知对于dp[i][j],随着j变小可选择的范围应逐渐增多,即如果dp[i][3] = 4,dp[i][1]最少为4,由此,再转移后再加入dp[i][j] = max(dp[i][j], dp[i][j+1])

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. using std :: max;
  5. const int maxn = 20000 + 100;
  6. int last[maxn], pre[maxn], other[maxn];
  7. int f[maxn][120];
  8. int n, k;
  9. int a[maxn];
  10. int tot = 0;
  11. int x1, x2;
  12. void add(int x, int y) {
  13. tot++;
  14. pre[tot] = last[x];
  15. last[x] = tot;
  16. other[tot] = y;
  17. }
  18. void dfs(int x, int from) {
  19. f[x][0] = a[x];
  20. for (int p = last[x]; p; p = pre[p]) {
  21. int q = other[p];
  22. if (q == from) continue;
  23. dfs(q, x);
  24. f[x][0] = f[x][0] + f[q][k];
  25. for (int j = 1; j <= k; j++) {
  26. f[x][j] = max(f[x][j] + f[q][max(k - j, j - 1)], f[x][max(k - j + 1, j)] + f[q][j-1]);
  27. }
  28. }
  29. for (int i = k-1; i >= 0; i--) f[x][i] = max(f[x][i+1], f[x][i]);
  30. }
  31. int main () {
  32. freopen("score.in", "r", stdin);
  33. freopen("score.out", "w", stdout);
  34. scanf("%d %d", &n, &k);
  35. for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  36. for (int i = 1; i < n; i++) {
  37. scanf("%d %d", &x1, &x2);
  38. add(x1, x2);
  39. add(x2, x1);
  40. }
  41. dfs(1, 0);
  42. printf("%d", f[1][0]);
  43. return 0;
  44. }

再贴上apt大犇的AC代码,代码略长但更为直观

  1. var
  2. n,m,a,b,bg :longint;
  3. f :array[0..10010,0..105]of longint;
  4. pre,oth,last,q,w :array[0..20010]of longint;
  5. vis :array[0..10010]of boolean;
  6. ii,i,j,k,p,r :longint;
  7. totl,ans,ret,mxs :longint;
  8. function max(a,b:longint):longint;
  9. begin
  10. if a>b then exit(a); exit(b);
  11. end;
  12. procedure conn(a,b:longint);
  13. begin
  14. inc(totl);
  15. pre[totl]:=last[a];
  16. last[a]:=totl;
  17. oth[totl]:=b;
  18. end;
  19. procedure bfs;
  20. var p,cur,r,he,ta:longint;
  21. begin
  22. he:=0; ta:=1; q[1]:=1; vis[1]:=true;
  23. while he<>ta do begin
  24. inc(he);
  25. cur:=q[he];
  26. p:=last[cur];
  27. while p>0 do begin
  28. r:=oth[p];
  29. if not vis[r] then begin
  30. vis[r]:=true;
  31. inc(ta);
  32. q[ta]:=r;
  33. end;
  34. p:=pre[p];
  35. end;
  36. end;
  37. end;
  38. begin
  39. assign(input,'score.in'); reset(input);
  40. assign(output,'score.out'); rewrite(output);
  41. read(n,m);
  42. for i:=1 to n do read(w[i]);
  43. for i:=1 to n-1 do begin
  44. read(a,b);
  45. conn(a,b); conn(b,a);
  46. end;
  47. bfs;
  48. bg:=(m>>1)+1;
  49. for ii:=n downto 1 do begin
  50. i:=q[ii];
  51. f[i,0]:=w[i];
  52. p:=last[i];
  53. while p>0 do begin
  54. r:=oth[p];
  55. inc(f[i,0],f[r,m]);
  56. p:=pre[p];
  57. end;
  58. for k:=m downto bg do begin
  59. f[i,k]:=f[i,k+1];
  60. ret:=0;
  61. p:=last[i];
  62. while p>0 do begin
  63. r:=oth[p];
  64. inc(ret,f[r,k-1]);
  65. p:=pre[p];
  66. end;
  67. f[i,k]:=max(f[i,k],ret);
  68. //if (k=3)and(i=1) then writeln('??',ret,' ',f[3,2],' ',f[i,k]);
  69. end;
  70. for k:=bg-1 downto 1 do begin
  71. f[i,k]:=f[i,k+1];
  72. ret:=0; mxs:=0;
  73. p:=last[i];
  74. while p>0 do begin
  75. r:=oth[p];
  76. inc(ret,f[r,m-k]);
  77. p:=pre[p];
  78. end;
  79. p:=last[i];
  80. while p>0 do begin
  81. r:=oth[p];
  82. f[i,k]:=max(f[i,k],ret-f[r,m-k]+f[r,k-1]);
  83. p:=pre[p];
  84. end;
  85. {if (k=2)and(i=1) then writeln('??',ret,' ',mxs,' ',f[2,1]);
  86. f[i,k]:=max(f[i,k],f[mxs,k-1]+ret-f[mxs,m-k]); }
  87. end;
  88. f[i,0]:=max(f[i,0],f[i,1]);
  89. end;
  90. {for i:=1 to n do begin
  91. for j:=0 to m do begin
  92. write(f[i,j],' ');
  93. end;
  94. writeln;
  95. end; }
  96. for i:=0 to m do
  97. ans:=max(ans,f[1,i]);
  98. write(ans);
  99. close(input);
  100. close(output);
  101. end.

T2:

线性dp,状态定义和转移都比较邪,,,

考试时把题目理解成处理玉的方案数,导致前期思路错误,未能完成题目

正解:

F[i]表示到了第i天恰好第一次出现k个连续的晴天的方案数,那么要保证i-k这一天一定是雨天或者X,于是i-k+1i这一段的天气已经全部被固定了,可以得出方案数有2^(1i-k中X的个数),然后减去所有不合法的状态,对于Fj就减去F[j]2^(j+1~i-k中X的个数)(可以记一个数组t1,每次遇到X就2,每次都加上F[i]的值),(j>i-k)的就是减去F[j],对于雨天反过来做一次,最后答案是sigma(F[i]*雨天的t1[i+1])

实现:

使用numx, numw, numb记录每种天气出现的次数,为方便期间,numx, numb 从1开始,numw从n逆向开始

转移

当题设条件满足时,f[i] = 2 ^ (numx[i-k-1]) - t[i - k - 1], ts[i] = (ts[i-1]) * (1 + (当前为x) ) + f[i]。

代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. const int mod = 1000000007;
  5. const int maxn = 1000000 + 100;
  6. int n, k;
  7. char s[maxn];
  8. long long pow2[maxn];
  9. int numb[maxn], numw[maxn], numx[maxn];
  10. long long fs[maxn], fr[maxn], ts[maxn], tr[maxn];
  11. int main () {
  12. freopen("jade.in", "r", stdin);
  13. freopen("jade.out", "w", stdout);
  14. scanf("%d %d", &n, &k);
  15. scanf("%s", s + 1);
  16. s[0] = 'X';
  17. s[n+1] = 'X';
  18. pow2[0] = 1;
  19. for (int i = 1; i <= n; i++) pow2[i] = (pow2[i-1] * 2) % mod;
  20. for (int i = 1; i <= n; i++) numb[i] = numb[i-1] + (s[i] == 'B');
  21. for (int i = n; i >= 1; i--) numw[i] = numw[i+1] + (s[i] == 'W');
  22. for (int i = 1; i <= n; i++) numx[i] = numx[i-1] + (s[i] == 'X');
  23. for (int i = k; i <= n; i++) {
  24. if ((numb[i] - numb[i-k] + numx[i] - numx[i-k]) == k && s[i-k] != 'B')
  25. fs[i] = ((pow2[numx[i - k - 1]] - ts[i - k - 1]) + mod) % mod;
  26. ts[i] = (ts[i-1] * (1 + (s[i] == 'X')) + fs[i]) % mod;
  27. }
  28. numx[n+1] = numx[n];
  29. for (int i = n - k + 1; i >= 1; i--) {
  30. if (numw[i] - numw[i + k] + numx[i + k - 1] - numx[i - 1] == k && s[i + k] != 'W')
  31. fr[i] = ((pow2[numx[n] - numx[i + k]] - tr[i + k + 1]) + mod) % mod;
  32. tr[i] = ( tr[i + 1] * (1 + (s[i] == 'X')) + fr[i] ) % mod;
  33. }
  34. long long ans = 0;
  35. //for (int i = 1; i <= n; i++) printf("%I64d ", ts[i]);
  36. for (int i = 1; i <= n; i++) ans = ((ans + fs[i] * tr[i + 1] % mod) + mod) % mod;
  37. printf("%I64d", ans);
  38. return 0;
  39. }

具体细节有待进一步讨论

具体细节有待进一步讨论

具体细节有待进一步讨论

具体细节有待进一步讨论

T3:

正在写。。。

2016 10 27 考试 dp 向量 乱搞的更多相关文章

  1. 2016 10 28考试 dp 乱搞 树状数组

    2016 10 28 考试 时间 7:50 AM to 11:15 AM 下载链接: 试题 考试包 这次考试对自己的表现非常不满意!! T1看出来是dp题目,但是在考试过程中并没有推出转移方程,考虑了 ...

  2. CF809E Surprise me!(莫比乌斯反演+Dp(乱搞?))

    题目大意: 给你一棵树,树上的点编号为\(1-n\).选两个点\(i.j\),能得到的得分是\(\phi(a_i*a_j)*dis(i,j)\),其中\(dis(i,j)\)表示\(a\)到\(b\) ...

  3. POJ 3671 DP or 乱搞

    思路: 1.DP f[i][j]:前i个数 最后一个数是j的最小花费 f[i][j]=min(f[i][j],f[i-1][k]+(a[i]!=j));1<=k<=j 这种做法比较有普遍性 ...

  4. 2016 10 26考试 NOIP模拟赛 杂题

    Time 7:50 AM -> 11:15 AM 感觉今天考完后,我的内心是崩溃的 试题 考试包 T1: 首先看起来是个贪心,然而,然而,看到那个100%数据为n <= 2000整个人就虚 ...

  5. hdu4714树形DP+贪心(乱搞)

    Tree2cycle A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...

  6. angular2 组件之间通讯-使用服务通讯模式 2016.10.27 基于正式版ng2

    工作中用到ng2的组件通讯 奈何官方文档言简意赅 没说明白 自己搞明白后 整理后分享下 rxjs 不懂的看这篇文章 讲很详细 http://www.open-open.com/lib/view/ope ...

  7. uoj#267. 【清华集训2016】魔法小程序(乱搞)

    传送门 感觉很像FFT的过程的说-- 先来考虑\(b\)如何转化成\(c\),那么只要通过它的逆过程就可以了 首先,我们称"魔法"为比较两个数的字典序,记\(x=a_0\),那么把 ...

  8. 2021.10.27考试总结[冲刺NOIP模拟17]

    T1 宝藏 发现每个数成为中位数的长度是关于权值单调的.线段树二分判断是否合法,单调指针扫即可. 考场上写了二分,平添\(\log\). \(code:\) T1 #include<bits/s ...

  9. My latest news (--2016.10)

    2016.10.31 22:44 一个“程序”,打代码占40%.思考占60% 2016.10.30 20:53 周末,话说今天有晚上讲座,还点名,了,悲催.之前学习的Qt有点问题,悲催.推荐个博文:h ...

随机推荐

  1. ios兼容 input输入时弹出键盘框 页面整体上移键盘框消失后在ios上页面不能回弹的问题

    前端h5混合开发手机端ios  当有input输入时,手机下方弹出键盘使页面上移,当输入完成,键盘消失后页面显示回到原位,但实际不能点击(可点击上方区域,有反应),也就是说实际是没有回弹. 解决办法: ...

  2. tensorflow的tf.train.Saver()模型保存与恢复

    将训练好的模型参数保存起来,以便以后进行验证或测试.tf里面提供模型保存的是tf.train.Saver()模块. 模型保存,先要创建一个Saver对象:如 saver=tf.train.Saver( ...

  3. HTML 编码规范

    语法 使用 4 个空格做为一个缩进层级,不允许使用 2 个空格或 tab 字符 在属性上,使用双引号 "",不要使用单引号 '' 属性名 / 属性值全小写,用中划线 - 做分隔符 ...

  4. zoj 3471 Most Powerful(状压dp+Tsp问题+连续性问题)

    上来直接一波敲键盘,直接套Tsp问题的代码 然后WA 发现貌似这道题没有连续性. Tsp问题是一条路径,一个点到另一个点,多了一个限制,所以就需要加多一维 而这道题没有限制,也就是说那一维不需要加,我 ...

  5. Python 爬虫练习: 爬取百度贴吧中的图片

    背景:最近开始看一些Python爬虫相关的知识,就在网上找了一些简单已与练习的一些爬虫脚本 实现功能:1,读取用户想要爬取的贴吧 2,读取用户先要爬取某个贴吧的页数范围 3,爬取每个贴吧中用户输入的页 ...

  6. Linux配置nignx虚拟主机

    Nginx 是一个轻量级高性能的 Web 服务器, 并发处理能力强, 对资源消耗小, 无论是静态服务器还是小网站, Nginx 表现更加出色, 作为 Apache 的补充和替代使用率越来越高. 我在& ...

  7. openfiler作为文件server,实现ISCSI共享存储

    还是不能发图.这是第二篇.图文在这个地址:http://download.csdn.net/detail/weimingyu945/8089893 1      登陆 首先登陆openfiler的we ...

  8. nyoj 585 取石子(六) 【Nim】

    取石子(六) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述 近期TopCoder的PIAOYI和HRDV非常无聊,于是就想了一个游戏,游戏是这种:有n堆石子,两个人 ...

  9. 判断一个整数是否是回文数C++实现 leetcode系列(九)

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向 ...

  10. 138.安全退出的异常,要用throw 尽量不用exit(0)

    #include<iostream> #include<cstdlib> using namespace std; ////非安全退出,结束进程, //C++ 必须释放对象,最 ...