传送门

Description

给你一个长度为\(2n\)的数字,每次可以从左侧选一个数字,加入连接到一个数字\(A\)或另一个数字\(B\)后面。\(A,B\)初始为\(0\)。\(A\)与\(B\)必须恰好被连接\(n\)次。最大化\(A,B\)的和,输出方案

Input

第一行是\(n\),第二行是长度为\(2n\)的数字

Output

从左到右输出该数字第几位被如何处理。连接到\(A\)输出\(H\),连接到\(B\)输出\(M\)。

Hint

\(1~\leq~n~\leq~18\)

Solution

看起来像是个DP啊……

考虑如果正向DP的话,每次选择一个数,数字和增加多少依赖于之前那个数字选了多少。这显然是有后效性的,难以处理。

考虑反过来DP。

这样每次选一个数只依赖于之前选了多少位,可以直接设到状态里面。于是可以设\(f_{i,j}\)为\(A\)选了\(i\)位,\(B\)选了\(j\)位的数字和,转移显然。

Code

  1. #include<cstdio>
  2. #define rg register
  3. #define ci const int
  4. #define cl const long long
  5. typedef long long int ll;
  6. template <typename T>
  7. inline void qr(T &x) {
  8. rg char ch=getchar(),lst=' ';
  9. while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
  10. while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
  11. if(lst == '-') x=-x;
  12. }
  13. namespace IO {
  14. char buf[120];
  15. }
  16. template <typename T>
  17. inline void qw(T x,const char aft,const bool pt) {
  18. if(x < 0) {x=-x,putchar('-');}
  19. rg int top=0;
  20. do {IO::buf[++top]=x%10+'0';} while(x/=10);
  21. while(top) putchar(IO::buf[top--]);
  22. if(pt) putchar(aft);
  23. }
  24. template <typename T>
  25. inline T mmax(const T a,const T b) {return a > b ? a : b;}
  26. template <typename T>
  27. inline T mmin(const T a,const T b) {return a < b ? a : b;}
  28. template <typename T>
  29. inline T mabs(const T a) {return a < 0 ? -a : a;}
  30. template <typename T>
  31. inline void mswap(T &_a,T &_b) {
  32. T _temp=_a;_a=_b;_b=_temp;
  33. }
  34. const int maxn = 40;
  35. const int INF = 0x3f3f3f3f;
  36. int n,dn;
  37. int MU[maxn];
  38. ll frog[maxn][maxn],ten[maxn]={1};
  39. char s[maxn];
  40. bool pre[maxn][maxn];
  41. void dfs(ci,ci);
  42. int main() {
  43. qr(n);
  44. scanf("%s",s+1);
  45. dn=n<<1;
  46. for(rg int i=dn;i;--i) MU[dn-i+1]=s[i]-'0';
  47. for(rg int i=1;i<n;++i) ten[i]=ten[i-1]*10ll;
  48. for(rg int i=0;i<maxn;++i) for(rg int j=0;j<maxn;++j) frog[i][j]=-INF;
  49. frog[0][0]=0;
  50. for(rg int i=0;i<=n;++i) {
  51. for(rg int j=0;j<=n;++j) {
  52. int len=i+j;
  53. if(i) frog[i][j]=frog[i-1][j]+MU[len]*ten[i-1];
  54. if(j) {
  55. if(frog[i][j] < frog[i][j-1]+MU[len]*ten[j-1]) {
  56. frog[i][j]=frog[i][j-1]+MU[len]*ten[j-1];pre[i][j]=true;
  57. }
  58. }
  59. }
  60. }
  61. dfs(n,n);
  62. putchar('\n');
  63. return 0;
  64. }
  65. void dfs(ci x,ci y) {
  66. if((!x) && (!y)) return;
  67. if(pre[x][y]) {putchar('H');dfs(x,y-1);}
  68. else {putchar('M');dfs(x-1,y);}
  69. }

Summary

在序列上的线性DP,当正向难以转移时,可以考虑反向DP。

【DP】【CF31E】 TV Game的更多相关文章

  1. T2980 LR棋盘【Dp+空间/时间优化】

    Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子, ...

  2. 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】

    最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...

  3. 【DP+树状数组】BZOJ1264-[AHOI2006]基因匹配Match

    [题目大意] 给定n个数和两个长度为n*5的序列,两个序列中的数均有1..n组成,且1..n中每个数恰好出现5次,求两个序列的LCS. [思路] 预处理每个数字在a[i]中出现的五个位置.f[i]示以 ...

  4. BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】

    题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看 ...

  5. 【DP|多重背包可行性】POJ-1014 Dividing

    Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...

  6. COGS 862. 二进制数01串【dp+经典二分+字符串】

    862. 二进制数01串 ★   输入文件:kimbits.in   输出文件:kimbits.out   简单对比 时间限制:1 s   内存限制:128 MB USACO/kimbits(译 by ...

  7. CodeForces - 597C Subsequences 【DP + 树状数组】

    题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...

  8. hihocoder1475 数组分拆【DP+前缀和优化】

    思路: DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ; 对于100%的数据,满足1<=N<=10 ...

  9. SPOJ130 【DP·背包选取特性】

    题意: 给你n个任务,每个任务有一个起始时间,持续时间,一个权值: 问你怎么分配得到最大值 思路: 数据好大..百度了一发意识到自己好菜啊!背包的特性. dp[i]代表前 i 个能构成的最大值. 对于 ...

  10. lightoj1145 【DP优化求方案】

    题意: 有一个k面的骰子,然后问你n个骰子朝上的面数字之和=s的方案: 思路: dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案: 显然 dp[i][j] = dp[i - 1][j - ...

随机推荐

  1. OpenLDAP介绍

    首先LDAP是一个轻量级的产品(LightWeight),是一个Directory(D),存取的协议(Access Protocol). 我要着重指出,LDAP是一个数据库,但是又不是一个数据库.说他 ...

  2. xshell—实现Linux与Windows之间的文件传递

    在Windows系统上,通过xshell连接Linux系统. 第一种使用方式:从Linux系统上下载文件到Windows系统. 准备工作: $ sudo apt-get install lrzsz 安 ...

  3. JQuery点击打开再点击关闭

    $("#03").click(function() { $("#03").show(speed); $("#03").css("c ...

  4. How to Manage Amazon-Fulfilled Orders - Cancel an Amazon-Fulfilled Order

    You may request to cancel customer orders that have a status of "Pending" or "Unshipp ...

  5. 2.airflow参数简介

    比较重要的参数: 参数 默认值 说明 airflow_home /home/airflow/airflow01 airflow home,由环境变量$AIRFLOW_HOME决定 dags_folde ...

  6. CSS3 使用 calc() 计算高度 vh px

    Viewport    viewport:可视窗口,也就是浏览器.    vw Viewport宽度, 1vw 等于viewport宽度的1%    vh Viewport高度, 1vh 等于view ...

  7. DCOM初步窥探二

    1.COM进程透明性表现在“组件对象和客户程序可以拥有各自的空间,也可以共享同一个进程空间”. COM负责把客户的调用正确传到组件对象中,并保证参数传递的正确性. 组件对象和客户代码不必考虑调用传递的 ...

  8. Python:模块学习——sys模块

    sys模块常见函数和变量 sys.argv:命令行参数,实现从程序外部向程序传递参数 [注]:(1) sys.argv[0] 表示代码本身的文件路径 (2)sys.argv是一个元组,可以用[ ]提取 ...

  9. [转帖]Linux 的UTC 和 GMT

    1.问题 对于装有Windows和Linux系统的机器,进入Windows显示的时间和Linux不一致,Linux中的时间比Windows提前8个小时. 2.解决方法 修改/etc/default/r ...

  10. javascript之彻底理解this

    彻底理解this,需要彻底理解函数 函数是复杂类型,存储在堆中.  函数是独立的, 对象中的方法只是对象中有个函数的引用 函数被调用时,调用者会像被调用者提供个上下文环境, 这个环境就是this 构造 ...