B Alice and Bob

•输入输出文件: alice.in/alice.out

•源文件名: alice.cpp/alice.c/alice.pas

• 时间限制: 1s 内存限制: 128M

题目描述

Alice 和 Bob 发明了一个新的游戏。给定一个序列{x0,x1,··· ,xn−1}。Alice得 到一个序列 {a0,a1,··· ,an−1},其中 ai 表示以 xi 结尾的最长上升子序列的长 度;Bob 得到一个序列 {b0,b1,··· ,bn−1},其中 bi 表示以 xi 开头的最长下降 子序列的长度。Alice的得分是序列 {a0,a1,··· ,an−1} 的和,Bob的得分是 {b0,b1,··· ,bn−1}的和。 输输输入入入 输入的第一行是 n,第二行是序列{a0,a1,··· ,an−1}。数据保证序列 a 可以由 至少一个 1 到 n 的排列得到。

输出
输出包含一行,表示 Bob 能得到的最高分数。
样例输入1
4 1 2 2 3
样例输出1
5
样例输入2
4 1 1 2 3
样例输出2
5
数据范围 对于 30%

的数据,N ≤ 1000

对于 100% 的数据,N ≤ 10^5

这道题一看到的时候觉得可做,马上写出了一个转移方程 f[i]表示从后往前值为 i 时最长的答案,觉得似乎只能从后面 的 a值小于i的地方转移过来,然后就比SCOIDay1T1简单,用同样的思路加树状数组就出来了。但是后来再检查的时候仔细推了一下,发现有些不对。

对于两个位置p,q(p<q) 如果a[p]>=a[q] 那么x[p]>x[q] ,这一点很显而易见,但是如果a[p]<a[q]并不能推出x[p]<x[q]比如x为1 6 2 5 3 4时a值为1 2 2 3 3 4 a[2]<a[6]但是x[2]>x[6],所以说有一定问题。我们发现,如果满足a[p]<a[q]&&x[p]>x[q]则一定存在另一个序列从p后面等于a[p]这个值开始,不断累加可以得到,比如a[2]后面a[3]==a[2] ,a[4]==a[3]+1,a[6]==a[4]+1,所以第6个位置可能比第二个位置小

然后就得到了一个暴力的方法,小于的像原来那样弄,大于的N^2来搞,这样子可以得30分

然后想优化,思想上比较麻烦,写起来很简单,直接看代码吧:

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <algorithm>
  4. #include <iostream>
  5. using namespace std;
  6. int lowbit(int x) {return x&-x;}
  7.  
  8. int num[];
  9. int n;
  10. void change(int data,int pos)
  11. {
  12. while (pos<=n)
  13. {
  14. num[pos]=max(num[pos],data);
  15. pos+=lowbit(pos);
  16. }
  17. }
  18.  
  19. int getans(int pos)
  20. {
  21. int ret=;
  22. while (pos>)
  23. {
  24. ret=max(ret,num[pos]);
  25. pos-=lowbit(pos);
  26. }
  27. return ret;
  28. }
  29.  
  30. int a[];
  31. int f[];
  32. int fself[];
  33. int nextc[];
  34. int nextb[];
  35. int last[];
  36. int maxd[];
  37. void pre()
  38. {
  39. for (int i=n;i>=;--i)
  40. {
  41. nextc[i]=last[a[i]];
  42. last[a[i]]=i;
  43. nextb[i]=last[a[i]+];
  44. }
  45. }
  46.  
  47. void trans(int k)
  48. {
  49. fself[k]=fself[nextb[k]];
  50. fself[k]=max(fself[k],maxd[a[k]]);
  51. }
  52.  
  53. int getbigans(int k)
  54. {
  55. return fself[nextc[k]]+;
  56. }
  57.  
  58. int viodp()
  59. {
  60. int ret=;
  61. for (int i=n;i>=;--i)
  62. {
  63. f[i]=;
  64. for (int j=i+;j<=n;++j)
  65. {
  66. if (a[j]<=a[i])
  67. f[i]=max(f[i],f[j]+);
  68. }
  69. int now=a[i];
  70. for (int j=i+;j<=n;++j)
  71. {
  72. if (a[j]<=now&&a[j]>a[i])
  73. f[i]=max(f[i],f[j]+);
  74. if (a[j]==now)
  75. {
  76. now=now+;
  77. }
  78. }
  79. ret+=f[i];
  80. }
  81. // cout<<endl;
  82. return ret;
  83. }
  84.  
  85. long long dp()
  86. {
  87. long long ret=;
  88. for (int i=n;i>=;--i)
  89. {
  90. int f=getans(a[i])+;
  91. f=max(f,getbigans(i));
  92. maxd[a[i]]=max(maxd[a[i]],f);
  93. trans(i);
  94. change(f,a[i]);
  95. ret+=f;
  96. }
  97. return ret;
  98. }
  99.  
  100. int main()
  101. {
  102. freopen ("alice.in","r",stdin);
  103. freopen ("alice.out","w",stdout);
  104. scanf("%d",&n);
  105. for (int i=;i<=n;++i)
  106. {
  107. scanf("%d",&a[i]);
  108. }
  109. if (n<=)
  110. {
  111. cout<<viodp()<<endl;
  112. return ;
  113. }
  114. pre();
  115. cout<<dp()<<endl;
  116. return ;
  117. }

Viodp就是暴力的DP

自己看着理解理解吧。。。其实我觉得这道DP不错,有些意思。似乎其他人写了什么拓扑排序只有50分。

关于TJOI2014的一道题——Alice and Bob的更多相关文章

  1. ACdream 1112 Alice and Bob(素筛+博弈SG函数)

    Alice and Bob Time Limit:3000MS     Memory Limit:128000KB     64bit IO Format:%lld & %llu Submit ...

  2. XTU OJ 1209 Alice and Bob 2014(嘉杰信息杯ACM/ICPC湖南程序设计邀请赛暨第六届湘潭市程序设计竞赛)

    Problem Description The famous "Alice and Bob" are playing a game again. So now comes the ...

  3. UOJ #266 【清华集训2016】 Alice和Bob又在玩游戏

    题目链接:Alice和Bob又在玩游戏 这道题就是一个很显然的公平游戏. 首先\(O(n^2)\)的算法非常好写.暴力枚举每个后继计算\(mex\)即可.注意计算后继的时候可以直接从父亲转移过来,没必 ...

  4. Foj 2296 Alice and Bob(博弈、搜索)

    Foj 2296 Alice and Bob 题意 两个人博弈,规则如下:轮流取0~9中的数字,最后Alice所得的数字个数为1~n中,数位在Alice所取集合中出现奇数次的. 双方想获得尽量多,问A ...

  5. hdu 4111 Alice and Bob 记忆化搜索 博弈论

    Alice and Bob Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  6. 2016中国大学生程序设计竞赛 - 网络选拔赛 J. Alice and Bob

    Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  7. bzoj4730: Alice和Bob又在玩游戏

    Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...

  8. Alice and Bob(2013年山东省第四届ACM大学生程序设计竞赛)

    Alice and Bob Time Limit: 1000ms   Memory limit: 65536K 题目描述 Alice and Bob like playing games very m ...

  9. sdutoj 2608 Alice and Bob

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2608 Alice and Bob Time L ...

随机推荐

  1. JavaScript day3(运算符)

    运算符(operator) 基本运算符: 算术运算符用于执行变量之间的算术运算,给定 y=5: 运算符 描述 例子 结果 + 加 x=y+2 x=7 - 减 x=y-2 x=3 * 乘 x=y*2 x ...

  2. Maven中更改默认JDK版本

    只要在settings.xml文件中加上如下标签即可.(我这里是默认的1.7版本) <profiles> <profile> <id>jdk-1.7</id& ...

  3. 使用官方组件下载图片,保存到MySQL数据库,保存到MongoDB数据库

    需要学习的地方,使用官方组件下载图片的用法,保存item到MySQL数据库 需要提前创建好MySQL数据库,根据item.py文件中的字段信息创建相应的数据表 1.items.py文件 from sc ...

  4. 原来PHP对象比数组用更少的内存

    一直以为php的数组更节省内存,从来没有测试过,今天因为要读取一个大配置文件作为pool.做了一次测试: 得出结论是 使用对象保存数据更好,花费的内存是数组array的1/4. 测试代码 class ...

  5. 00105_UDP和TCP协议

    1.UDP协议 (1)UDP是User Datagram Protocol的简称,称为用户数据报协议: (2)UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接: (3)当一台 ...

  6. Sum of Medians

    Sum of Medians time limit per test 3 seconds memory limit per test 256 megabytes In one well-known a ...

  7. Mysql双主自增长冲突处理

    Mysql双主自增长冲突处理   多主互备和主从复制有一些区别,因为多主中都可以对服务器有写权限,所以设计到自增长重复问题   出现的问题(多主自增长ID重复)  1:首先我们通过A,B的test表结 ...

  8. [Usaco2010 Mar]gather 奶牛大集会

    [Usaco2010 Mar]gather 奶牛大集会 题目 Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会.每个奶牛居住在 ...

  9. 清北学堂模拟赛d6t3 反击数

    分析:显然是一道数位dp题,不过需要一些奇怪的姿势.常规的数位dp能统计出一个区间内满足条件的数的个数,可是我们要求第k个,怎么办呢?转化为经典的二分问题,我们二分当前数的大小,看它是第几大的,就可以 ...

  10. P - How many

    Give you n ( n < 10000) necklaces ,the length of necklace will not large than 100,tell me How man ...