这个题目上周的对抗赛的,美国2013区域赛的题目,上次比赛真惨,就做出一道题,最多的也只做出两道,当时想把这题做出来,一直TLE。

这个题目用挂在Hunnu OJ的数据可以过,但UVALive上死活过不了,好像UVALive卡的时间不太对,没人过了这道题。

我当初是想用一个dp[s]表示键入状态,然后由dp[0]开始逐渐向上深搜,结果就TLE了,后来比较了一下别人的代码,,果然我这样还是不行

不管我怎么优化,我这一维数组,不能对某个状态马上就返回,因为随时可以再被更新,但是如果用个二维数组,dp[s][i],表示在状态为s的时候,键入第i个字符时候的最小键入数目,就可以只更新一次,下次再遇到这个情况就能马上return了

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define N 18
  6. #define INF 1<<30
  7. using namespace std;
  8. char ch[N];
  9. int len,dp[<<N][N],ALL;
  10. //int up[1<<N][N];
  11. /*
  12. int abs(int a,int b)
  13. {
  14. if (a>b) return a-b;
  15. else return b-a;
  16. }
  17. */
  18. int diff(int a, int b) //这个函数和下面的函数都是计算转换字符的按键数,结果下面那个是错的,原因是在计算从Z字母转换过去的时候,下面那个算错了,没照顾到a在b的后面的情况。为了这个BUG我检查了好久 真不应该啊
  19. {
  20. int ans=abs(a-b);
  21. return min(ans,'Z'-'A'-ans+);
  22. }
  23. int ccounts(char a,char b)
  24. {
  25. int asc1=a-'A';
  26. int asc2=b-'A';
  27. int z='Z'-'A';
  28. int press=abs(asc1-asc2);
  29. press=min((press),z-asc2++asc1);
  30. return press;
  31.  
  32. }
  33. /*
  34. void solve(int s,int d)
  35. {
  36. if (d==len) return;
  37. //if (vis[s]) return;
  38. vis[s]=1;
  39. if (dp[ALL]<=dp[s]) return;
  40. for (int i=0; i<len; i++)
  41. {
  42. if ((1<<i)&s) continue;
  43. int nt=s+(1<<i);
  44. int tmp;
  45. //cout<<"p1"<<endl;
  46. //if (up[s][i]==0)
  47. //up[s][i]=counts(i,s,ch[i]);
  48. tmp=dp[s]+counts(i,s,ch[i]);
  49. //cout<<"p2"<<endl;
  50. //cout<<tmp<<endl;
  51. if (dp[nt]>tmp)
  52. {
  53. dp[nt]=tmp;
  54. mouse[nt]=i+1;
  55. action[nt]=ch[i]-'A';
  56. solve(nt,d+1);
  57. }
  58. else
  59. if (vis[nt]==0)
  60. solve(nt,d+1);
  61. //cout<<"p3"<<endl;
  62. //cout<<dp[nt]<<endl;
  63.  
  64. }
  65. }
  66. */
  67. int solve (int s,int last) //记忆化搜索
  68. {
  69. if (dp[s][last]) return dp[s][last];
  70. if (s==) return ;
  71. dp[s][last]=INF;
  72. int pos=;
  73. for (int i=;i<=last;i++)
  74. {
  75. if ((<<i)&s) pos++;
  76. }
  77. for (int i=,j=;i<len;i++)
  78. {
  79. if ((<<i)&s)
  80. {
  81. j++;
  82. if (j==pos) continue;
  83. int cur= j>pos? j-pos:pos-j-;
  84. int rng=diff(ch[i],ch[last]);
  85. dp[s][last]=min(dp[s][last],+cur+rng+solve(s^(<<last),i));
  86. }
  87. }
  88. return dp[s][last];
  89.  
  90. }
  91. int main()
  92. {
  93. //init();
  94. while (scanf("%s",ch))
  95. {
  96. len=strlen(ch);
  97. if (len== && ch[]=='') break;
  98. memset(dp,,sizeof dp);
  99. ALL=<<len;
  100. ALL--;
  101. for (int i=;i<len;i++)
  102. {
  103. dp[<<i][i]=diff('A',ch[i])+;
  104. }
  105. int ans=INF;
  106. for (int i=;i<len;i++){
  107. ans=min(ans,solve(ALL,i));
  108. }
  109. printf("%d\n",ans);
  110. }
  111. return ;
  112. }

UVALive 6491 You win! 状态DP的更多相关文章

  1. hdu 4614 pieces 状态DP

    题意:给你一个长度小于等于16的字符串,每次可以删除一个回文传,问你最少删除干净的字数. 状态+dp dp[i] = min(dp[i],dp[j]+dp[j^i]);(j是i的字串): 连接:htt ...

  2. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  3. POJ 3254 压缩状态DP

    题意:一个矩形网格,可以填0或1, 但有些位置什么数都不能填,要求相邻两个不同时为1,有多少种填法.矩形大小最大 12*12. 压缩状态DP大多有一个可行的state的范围,先求出这个state范围, ...

  4. 【状态DP】 HDU 1074 Doing Homework

    原题直通车:HDU  1074  Doing Homework 题意:有n门功课需要完成,每一门功课都有时间期限t.完成需要的时间d,如果完成的时间走出时间限制,就会被减 (d-t)个学分.问:按怎样 ...

  5. Hdu 4539 【状态DP】.cpp

    题意: 一个炮兵可以攻打和他之间曼哈顿距离为2的士兵,给出你一块n*m的战场,告诉你哪些地方可以站人哪些地方不可以,问你最多可以安放多少个士兵? n <= 100, m <= 10 思路: ...

  6. hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)

    http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...

  7. hdu 5135(2014广州—状态dp)

    t题意:给你n条边,构造任意个三角形,一个三角形恰好只用3条边,每条边只能一次,求面积最大值 思路: 最开始想的是先排序从大到小取,但感觉并不怎么靠谱. 最多12条边,所以可以求出所有可能的三角形面积 ...

  8. Hdu 3001 Travelling 状态DP

    题目大意 一次旅游,经过所有城市至少一次,并且任何一座城市访问的次数不能超过两次,求最小费用 每个城市最多访问两次,用状态0,1,2标识访问次数 把城市1~N的状态按照次序连接在一起,就组成了一个三进 ...

  9. lightoj 1244 - Tiles 状态DP

    思路:状态DP dp[i]=2*dp[i-1]+dp[i-3] 代码如下: 求出循环节部分 1 #include<stdio.h> 2 #define m 10007 3 int p[m] ...

随机推荐

  1. 【Leetcode】交替打印FooBar

    [问题]我们提供一个类: class FooBar { public void foo() { ; i < n; i++) { print("foo"); } } publi ...

  2. Python 实现类似range函数

    需求:写一个属于你自己的 frange函数,frange与range类似,一样的参数规则,但是每一项必须要是float类型 实现: 注意点,如何判断stop是否有参数传入,这里使用空字符判断,如fra ...

  3. 09.swoole学习笔记--进程事件

    <?php //进程数组 $workers=[]; //创建进程的数据量 $worker_num=; //创建启动进程 ;$i<$worker_num;$i++){ //创建单独新进程 $ ...

  4. 五十三、SAP中创建一个LVC表格

    一.我们打开之前的程序,在函数里面创建一个名字为SHOW_DATA_LVCE的函数 二.点击编辑->模式 三.选择'REUSE_ALV_GRID_DISPLAY_LVC' 四.选择调用功能,点击 ...

  5. Bootstrap 侧边栏 导航栏

    http://blog.csdn.net/shangmingchao/article/details/49763351 实测效果图:

  6. module已经装了但仍提示找不到的解决方法

    今天遇到的问题:(这里只是个例子) 解决方法: npm clean cache --force 删了node_modules 和 package-lock ,然后npm install 如果再不行,看 ...

  7. 代做Assignment时排比结构的使用解析

    排比句式的作用想必各位留学生都不陌生,同理,在英文写作中,不管是从形式还是内容上来说,排比结构的作用都是强调.但是要注意,不能在分析的时候用太多这种套话,尽量还是能够根据具体情况具体分析.静态,小编将 ...

  8. Windows + Python + flup + flask + fastcgi + Nginx配置

    Nginx配置 # HTTPS server { listen ssl; server_name kvaccount.xx.io; ssl_certificate "C:/xx/conf/s ...

  9. Spark SQL 笔记

    Spark SQL 简介 SparkSQL 的前身是 Shark, SparkSQL 产生的根本原因是其完全脱离了 Hive 的限制.(Shark 底层依赖于 Hive 的解析器, 查询优化器) Sp ...

  10. 浅谈Python 中 __getattr__与__getattribute__的区别

    __getattr__与__getattribute__均是一般实例属性截取函数(generic instance attribute interception method),其中,__getatt ...