题目链接:http://codeforces.com/contest/909/problem/C

题意:

  Python是没有大括号来标明语句块的,而是用严格的缩进来体现。

  现在有一种简化版的Python,只有两种语句:

    (1)'s'语句:Simple statements. 相当于一般语句。

    (2)'f'语句:For statements. 相当于for循环,并且规定它的循环体不能为空。

  然后给你一段没有缩进的Python程序,共n行(n <= 5000)。

  问你添加缩进后,有多少种合法且不同的Python程序。

题解:

  表示状态:

    dp[i][j] = numbers

    考虑到第i行,并且第i行的缩进有j个Tab时的合法方案数。

  找出答案:

    ans = ∑ dp[n-1][0 to n-1]

    行号从0开始标。并且对于第i行来说,它的缩进最多有i个Tab。

  如何转移:

    两种情况。

    当前为dp[i][j](用顺推)。

    (1)第i行为'f',则第i+1行的缩进只能为j+1。

      dp[i+1][j+1] += dp[i][j]

    (2)第i行为's',则第i+1行的缩进可以为[0,j]中的任意一种。

      dp[i+1][0 to j] += dp[i][j]

  边界条件:

    dp[0][0] = 1

    第0行的缩进只能为0。

  树状数组优化:

    如果按照上面的方程直接去写的话,枚举状态为O(N^2),转移的第二种情况复杂度为O(N)。

    所以最坏情况下为O(N^3),对于N = 5000肯定炸了……

    所以考虑用树状数组来实现转移的第二种情况,也就是区间加法和单点查询。

    于是总复杂度变为O(N^2*logN)。

    另外,树状数组下标从1开始,所以之前所有的下标都要+1。

  update:

    其实顺推也可以用差分优化掉一个n的啊……

    (打比赛的时候人是瓷的……)

AC Code:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #define MAX_N 5005
  5. #define MOD 1000000007
  6.  
  7. using namespace std;
  8.  
  9. int n;
  10. int dp[MAX_N][MAX_N];
  11. char c[MAX_N];
  12.  
  13. void update(int *dat,int k,int x)
  14. {
  15. while(k>)
  16. {
  17. dat[k]=(dat[k]+x)%MOD;
  18. k-=k&-k;
  19. }
  20. }
  21.  
  22. int query(int *dat,int k)
  23. {
  24. int sum=;
  25. while(k<=n)
  26. {
  27. sum=(sum+dat[k])%MOD;
  28. k+=k&-k;
  29. }
  30. return (sum%MOD+MOD)%MOD;
  31. }
  32.  
  33. void sec(int *dat,int l,int r,int x)
  34. {
  35. update(dat,r,x);
  36. update(dat,l-,-x);
  37. }
  38.  
  39. int main()
  40. {
  41. cin>>n;
  42. for(int i=;i<=n;i++) cin>>c[i];
  43. memset(dp,,sizeof(dp));
  44. sec(dp[],,,);
  45. for(int i=;i<=n;i++)
  46. {
  47. for(int j=;j<=i;j++)
  48. {
  49. int now=query(dp[i],j);
  50. if(now)
  51. {
  52. if(c[i]=='f')
  53. {
  54. sec(dp[i+],j+,j+,now);
  55. }
  56. else
  57. {
  58. sec(dp[i+],,j,now);
  59. }
  60. }
  61. }
  62. }
  63. int ans=;
  64. for(int i=;i<=n;i++)
  65. {
  66. ans=(ans+query(dp[n],i))%MOD;
  67. }
  68. cout<<ans<<endl;
  69. }

Codeforces 909C Python Indentation:树状数组优化dp的更多相关文章

  1. Codeforces 946G Almost Increasing Array (树状数组优化DP)

    题目链接   Educational Codeforces Round 39 Problem G 题意  给定一个序列,求把他变成Almost Increasing Array需要改变的最小元素个数. ...

  2. HDU 6240 Server(2017 CCPC哈尔滨站 K题,01分数规划 + 树状数组优化DP)

    题目链接  2017 CCPC Harbin Problem K 题意  给定若干物品,每个物品可以覆盖一个区间.现在要覆盖区间$[1, t]$. 求选出来的物品的$\frac{∑a_{i}}{∑b_ ...

  3. LUOGU P2344 奶牛抗议 (树状数组优化dp)

    传送门 解题思路 树状数组优化dp,f[i]表示前i个奶牛的分组的个数,那么很容易得出$f[i]=\sum\limits_{1\leq j\leq i}f[j-1]*(sum[i]\ge sum[j- ...

  4. 【题解】Music Festival(树状数组优化dp)

    [题解]Music Festival(树状数组优化dp) Gym - 101908F 题意:有\(n\)种节目,每种节目有起始时间和结束时间和权值.同一时刻只能看一个节目(边界不算),在所有种类都看过 ...

  5. 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)

    [题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...

  6. Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)

    题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...

  7. BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】

    Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...

  8. BZOJ 3594: [Scoi2014]方伯伯的玉米田 (二维树状数组优化DP)

    分析 首先每次增加的区间一定是[i,n][i,n][i,n]的形式.因为如果选择[i,j](j<n)[i,j](j<n)[i,j](j<n)肯定不如把后面的全部一起加111更优. 那 ...

  9. 4.9 省选模拟赛 划分序列 二分 结论 树状数组优化dp

    显然发现可以二分. 对于n<=100暴力dp f[i][j]表示前i个数分成j段对于当前的答案是否可行. 可以发现这个dp是可以被优化的 sum[i]-sum[j]<=mid sum[i] ...

随机推荐

  1. OneThink生成分类树方法(list_to_tree)使用!

    具体方法: Application / Common / Common / function.php 下的 224行: function list_to_tree($list, $pk='id', $ ...

  2. 310实验室OTL问题----将写好的C++文件转换成Python文件,并将数据可视化

    如图:文件夹 第一处:optimizer文件夹下的:optimizer.h文件中添加你所写代码的头文件  #include <OTL/Optimizer/Reference-NSGA-II/Re ...

  3. Tomcat 400错误 问题集锦

    1.前后台参数类型不一致 上图错误提示就是客户端发送的请求不能找到你的具体的页面或者地址,这是Spring MVC抛出的错误,这样我们就要进行参数的检查,一定是JSP提交的参数和Controller里 ...

  4. 170711、Linux下搭建MySQL集群

    一.MySQL集群简介 1.什么是MySQL集群 MySQL集群是一个无共享的(shared-nothing).分布式节点架构的存储方案,其目的是提供容错性和高性能. 数据更新使用读已提交隔离级别(r ...

  5. 基于JDK1.8的LinkedList源码学习笔记

    LinkedList作为一种常用的List,是除了ArrayList之外最有用的List.其同样实现了List接口,但是除此之外它同样实现了Deque接口,而Deque是一个双端队列接口,其继承自Qu ...

  6. js封装正则验证

    //根据不同的验证内容,返回相应的正则表达式 function returnRegString(regName) { if (regName == "email") { retur ...

  7. LAMP开发(1)

    apache web服务器软件,最近款的有7兆大小,工作:监听端口,接收请求,解析HTTP协议,转发给PHP比如:当一个客户端的请求发过来的时候,通常客户端(浏览器),请求发送给某一台IP,这个IP肯 ...

  8. Qt::浅谈信号槽连接,参数在多线程中的使用

    Qt的信号槽有五种连接方式定义在enum Qt::ConnectionType,下面简单介绍 Qt::AutoConnection:自动判断连接方式,如果信号发送对象和执行槽对象在同一线程,那么等于Q ...

  9. Java 如何中断和恢复线程的执行

    一.线程的状态 线程可以阻塞于四种状态: 1.当线程执行Thread.sleep()时,它一直阻塞到指定的毫秒时间之后,或者阻塞被另一个线程打断: 2.当线程碰到一条wait()语句时,它会一直阻塞到 ...

  10. qt——类大全

    qt类总结地址 http://www.kuqin.com/qtdocument/ QWidget.QDialog及QMainWindow的区别 QWidget类是所有用户界面对象的基类. 窗口部件是用 ...