cug oj 1479 Treasure Chest Lock (区间dp 思维)

1479: Treasure Chest Lock

Time Limit: 1 Sec  Memory Limit: 128 MB

Submit: 7  Solved: 5

[Submit][Status][Web
Board
]

Description

Vic has a treasure chest. And there is a lock on the treasure chest. The lock contains a sequence of wheels. Each wheel has the 26 letters of the English alphabet

‘a’ through ‘z’, in order. If you move a wheel up, the letter it shows changes to the next letter in the English alphabet (if it was showing the last letter ‘z’, then it

changes to ‘a’). If you move the wheel down, it changes to show the previous letter in the English alphabet (if it was showing ‘a’, then it changes to ‘z’).

It is also possible to move any subsequence of contiguous wheels in the same direction with only one movement. This has the same effect of moving each of the

wheels within the subsequence on that direction, but saves the effort of doing that one wheel at a time.The lock openswhen the wheels show a secret sequence of l

etters. Currently all wheels are showing the letter ‘a’. Vic wants to know the minimum number of movements you need to open the lock.

Input

The input has several test cases. Each of them is given in exactly one line containing a nonempty string of at most 1000 lowercase letters. The string represents

the secret sequence of letters that opens the lock.

Output

For each test case, output a line containing a single integer with the minimum number of movements to open the lock.

Sample Input

abcxyzabcdefghijklmnopqrstuvwxyzaaaaaaaaazzzzzzzzzzzzzbzzzz*

Sample Output

525013

题意:

给你一个字符串,每次可以选择一个子串ss,将ss整体+1或者整体-1,a+1=b,a+1=a。要将所有字符全变为a,问最小的步数。

思路:

可以想到两种属性相反的操作(一加一减)不可能重叠,如果重叠的话,可以修改它们到不重叠也达到相同的效果。然后每个字符就是通过一系列‘+‘操作或者‘-’操作(只能选其1)得到a的。但是可以+或者-很多次,不信可以看这个例子,mtezqh,答案为30.

dn[i][j]表示到将前i个字符全部变为a,最后一个字符‘-’j圈(如果j=0,只需操作s[j]-‘a‘次)最小步数。

up[i][j]表示到将前i个字符全部变为a,最后一个字符‘+’j圈(如果j=0,只需操作‘a+‘26-s[j]-次)最小步数。

然后递推即可。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 1005
#define MAXN 200005
#define INF 0x3f3f3f3f
#define mod 20140518
#define eps 1e-6
const double pi=acos(-1.0);
typedef long long ll;
using namespace std;

int n,m;
int up[maxn][40],dn[maxn][40];
char s[maxn];

void solve()
{
    int i,j,k;
    n=strlen(s+1);
    memset(dn,0x3f,sizeof(dn));
    memset(up,0x3f,sizeof(up));
    dn[1][0]=s[1]-'a';
    up[1][0]='a'+26-s[1];
    for(i=1; i<n; i++)
    {
        for(j=0; j<30; j++)
        {
            if(s[i+1]==s[i])
            {
                dn[i+1][j]=dn[i][j];
                up[i+1][j]=up[i][j];
            }
            else if(s[i+1]<s[i])
            {
                if(dn[i][j]<INF)
                {
                    dn[i+1][j]=min(dn[i+1][j],dn[i][j]);
                    if(j>0) dn[i+1][j-1]=min(dn[i+1][j-1],dn[i][j]);
                    dn[i+1][j+1]=min(dn[i+1][j+1],dn[i][j]+s[i+1]-s[i]+26);
                    up[i+1][0]=min(up[i+1][0],dn[i][j]+'a'+26-s[i+1]);
                }
                if(up[i][j]<INF)
                {
                    up[i+1][j]=min(up[i+1][j],up[i][j]+s[i]-s[i+1]);
                    if(j>0) up[i+1][j-1]=min(up[i+1][j-1],up[i][j]);
                    up[i+1][j+1]=min(up[i+1][j+1],up[i][j]+s[i]-s[i+1]+26);
                    dn[i+1][0]=min(dn[i+1][0],up[i][j]+s[i+1]-'a');
                }
            }
            else
            {
                if(dn[i][j]<INF)
                {
                    dn[i+1][j]=min(dn[i+1][j],dn[i][j]+s[i+1]-s[i]);
                    if(j>0) dn[i+1][j-1]=min(dn[i+1][j-1],dn[i][j]);
                    dn[i+1][j+1]=min(dn[i+1][j+1],dn[i][j]+s[i+1]-s[i]+26);
                    up[i+1][0]=min(up[i+1][0],dn[i][j]+'a'+26-s[i+1]);
                }
                if(up[i][j]<INF)
                {
                    up[i+1][j]=min(up[i+1][j],up[i][j]);
                    if(j>0) up[i+1][j-1]=min(up[i+1][j-1],up[i][j]);
                    up[i+1][j+1]=min(up[i+1][j+1],up[i][j]+s[i]-s[i+1]+26);
                    dn[i+1][0]=min(dn[i+1][0],up[i][j]+s[i+1]-'a');
                }
            }
        }
    }
    int ans=min(dn[n][0],up[n][0]);
    printf("%d\n",ans);
}
int main()
{
    while(~scanf("%s",s+1))
    {
        if(s[1]=='*') break ;
        solve();
    }
    return 0;
}
/*
mtezqh
ans 30 e -26-e
*/

525013

时间: 2024-10-11 22:22:57

cug oj 1479 Treasure Chest Lock (区间dp 思维)的相关文章

light oj 1422 - Halloween Costumes (区间dp)

1422 - Halloween Costumes PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is planning to attend as many parties as he can. Since it's Ha

Light OJ 1031 - Easy Game(区间DP)

题目大意: 给你一个n,代表n个数字,现在有两个选手,选手A,B轮流有有一次机会,每个选手一次可以得到一个或者多个数字,从左侧或者右侧,但是不能同时从两边取数字,当所有的数字被取完,那么游戏结束.然后计算每个选手所得到数字的总和,每个选手都尽量让自己的分数比较多,选手A先开始取数.假设每个选手取得数字都是最优的,问A最多比B多多少分数,. 题目分析: 记忆化搜索,区间DP. dp[该谁取了][左区间L][右区间] = 所能取到的最大值. 做下简单的预处理,得到区间L-R之间的和. 然后状态转移

Light oj 1044 - Palindrome Partitioning(区间dp)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1044 dp[i][j]表示i到j直接的最小回文区间个数,直接看代码 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e3 + 5; 4 int dp[N][N], inf = 1e9; 5 char str[N]; 6 bool judge(int l, int r) { 7 for(int i

BZOJ 2101: [Usaco2010 Dec]Treasure Chest 藏宝箱( dp )

dp( l , r ) = sum( l , r ) - min( dp( l + 1 , r ) , dp( l , r - 1 ) ) 被卡空间....我们可以发现 l > r 是无意义的 , 所以可以省下一半的空间 -------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<a

一道看似dp实则暴力的题 Zombie&#39;s Treasure Chest

 Zombie's Treasure Chest 本题题意:有一个给定容量的大箱子,此箱子只能装蓝宝石和绿宝石,假设蓝绿宝石的数量无限,给定蓝绿宝石的大小和价值,要求是获得最大的价值 题解:本题看似是dp中的背包问题,但是由于数据量太大,用dp肯定会超时,所以只能寻找另外一种思路,可以用贪心加暴力,先求出两种宝石大小的最小公倍数com,然后将N/com-com,与N%comkanchengs看成是两个部分(想想应该明白).将前一个部分,放入单位价值量最高的那个,对于后面那个部分直接将S1的数量从

[Swust OJ 360]--加分二叉树(区间dp)

题目链接:http://acm.swust.edu.cn/problem/360/ Time limit(ms): 1000 Memory limit(kb): 65535 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下: subtree的左子树的加分×

洛谷P3004 [USACO10DEC]宝箱Treasure Chest

P3004 [USACO10DEC]宝箱Treasure Chest 题目描述 Bessie and Bonnie have found a treasure chest full of marvelous gold coins! Being cows, though, they can't just walk into a store and buy stuff, so instead they decide to have some fun with the coins. The N (1

洛谷 P3004 [USACO10DEC]宝箱Treasure Chest

P3004 [USACO10DEC]宝箱Treasure Chest 题目描述 Bessie and Bonnie have found a treasure chest full of marvelous gold coins! Being cows, though, they can't just walk into a store and buy stuff, so instead they decide to have some fun with the coins. The N (1

黑书例题 Fight Club 区间DP

题目可以在bnuoj.soj等OJ上找到. 题意: 不超过40个人站成一圈,只能和两边的人对战.给出任意两人对战的输赢,对于每一个人,输出是否可能是最后的胜者. 分析: 首先序列扩展成2倍,破环成链. dp[i][j]表示i和j能够相遇对打,那么dp[i][i+n]为真代表可以成为最后胜者. 枚举中间的k,若i和j都能和k相遇,且i和j至少一人能打赢k,那么i和j可以相遇. 复杂度o(n^3) 1 #include<cstdio> 2 #include<cstring> 3 usi