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

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

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

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

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 18
#define INF 1<<30
using namespace std;
char ch[N];
int len,dp[<<N][N],ALL;
//int up[1<<N][N];
/*
int abs(int a,int b)
{
if (a>b) return a-b;
else return b-a;
}
*/
int diff(int a, int b) //这个函数和下面的函数都是计算转换字符的按键数,结果下面那个是错的,原因是在计算从Z字母转换过去的时候,下面那个算错了,没照顾到a在b的后面的情况。为了这个BUG我检查了好久 真不应该啊
{
int ans=abs(a-b);
return min(ans,'Z'-'A'-ans+);
}
int ccounts(char a,char b)
{
int asc1=a-'A';
int asc2=b-'A';
int z='Z'-'A';
int press=abs(asc1-asc2);
press=min((press),z-asc2++asc1);
return press; }
/*
void solve(int s,int d)
{
if (d==len) return;
//if (vis[s]) return;
vis[s]=1;
if (dp[ALL]<=dp[s]) return;
for (int i=0; i<len; i++)
{
if ((1<<i)&s) continue;
int nt=s+(1<<i);
int tmp;
//cout<<"p1"<<endl;
//if (up[s][i]==0)
//up[s][i]=counts(i,s,ch[i]);
tmp=dp[s]+counts(i,s,ch[i]);
//cout<<"p2"<<endl;
//cout<<tmp<<endl;
if (dp[nt]>tmp)
{
dp[nt]=tmp;
mouse[nt]=i+1;
action[nt]=ch[i]-'A';
solve(nt,d+1);
}
else
if (vis[nt]==0)
solve(nt,d+1);
//cout<<"p3"<<endl;
//cout<<dp[nt]<<endl; }
}
*/
int solve (int s,int last) //记忆化搜索
{
if (dp[s][last]) return dp[s][last];
if (s==) return ;
dp[s][last]=INF;
int pos=;
for (int i=;i<=last;i++)
{
if ((<<i)&s) pos++;
}
for (int i=,j=;i<len;i++)
{
if ((<<i)&s)
{
j++;
if (j==pos) continue;
int cur= j>pos? j-pos:pos-j-;
int rng=diff(ch[i],ch[last]);
dp[s][last]=min(dp[s][last],+cur+rng+solve(s^(<<last),i));
}
}
return dp[s][last]; }
int main()
{
//init();
while (scanf("%s",ch))
{
len=strlen(ch);
if (len== && ch[]=='') break;
memset(dp,,sizeof dp);
ALL=<<len;
ALL--;
for (int i=;i<len;i++)
{
dp[<<i][i]=diff('A',ch[i])+;
}
int ans=INF;
for (int i=;i<len;i++){
ans=min(ans,solve(ALL,i));
}
printf("%d\n",ans);
}
return ;
}

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. 1.Maven分模块,分工程管理,多Web应用合并war包

    Eclipse 创建Maven工程 修改POM文件   Eclipse 创建Module工程 以此类推,创建Maven 的Modules web工程goodsmgrweb,创建Maven的Module ...

  2. 加傲腾内存的电脑PE无法识别本地磁盘解决办法(M.2接口??)

    ---恢复内容开始--- PE一直无法识别本地硬盘一直以为是主板设置的事情!原来是新兴的接口(M.2固态具体我不大明白)的事情,需要磁盘驱动,因为PE是精简的大多数不带驱动,但是2018年的新更新的P ...

  3. 【转载】UnityWebRequest的初步使用及常用方法解析

    文章来源:https://blog.csdn.net/qwe25878/article/details/85051911#_35 今天,来学习一下Unity新的网络请求方式UnityWebReques ...

  4. Java For 循环

    章节 Java 基础 Java 简介 Java 环境搭建 Java 基本语法 Java 注释 Java 变量 Java 数据类型 Java 字符串 Java 类型转换 Java 运算符 Java 字符 ...

  5. 06 MySQL运算符

    算数运算符     +    -    *    /    DIV    %    MOD   比较运算符     =    <>    !=    <=>(安全等于,NULL ...

  6. 关于VMware vSphere Client安装时,.net framework4进度条卡住不动(亲测)

    亲测有用的办法 1.点击电脑桌面右下角的"开始"按钮,点击"运行"按钮,在弹出的节目输入框中输入"regedit". 2.在弹出来的&quo ...

  7. 中文文本分类之CharCNN

    文本分类是自然语言处理中一个非常经典的任务,可用的模型非常多,相关的开源代码也非常多了.这篇博客用一个CNN模型,对新闻文本进行分类. 全部代码有4个模块:1.数据处理模块(命名为:cnews_loa ...

  8. 11.swoole学习笔记--进程信号触发器

    <?php //触发函数--异步执行 swoole_process::signal(SIGALRM,function(){ ; echo "$i \n"; $i++; ){ ...

  9. junit基础学习之-引用spring容器的测试(7)

    context 自动注入的文章链接:http://www.360doc.com/content/11/0815/09/2371584_140471325.shtml

  10. C# 使用复选框实现循环添加多条信息入库!

    先在前台获取到所有要添加信息的Id $('.imgid').each(function () {                     if ($(this).attr("src" ...