codeforces132C

题意:有个乌龟在一条线上走,初始位置为1
给你一串FT字符串代表指令,F代表朝着当前前进的方向走一步,T代表转向,再给你转换次数n,
每次可以把T变F,F变T,同一个指令可以变多次
问你在转换了n次的情况下,走的最远距离(假设初始位置为0,最远左边为o则答案为abs(o - 0))

很恶心的dp
dp[i][j][k][l] 已经执行了i指令,已经改变了j次,当前位置为k,朝向为l是否合法
最后遍历一遍k, l搜最远的k就行了

//
//  Created by Matrix on 2016-01-22
//  Copyright (c) 2015 Matrix. All rights reserved.
//
//
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <sstream>
#include <set>
#include <vector>
#include <stack>
#define ALL(x) x.begin(), x.end()
#define INS(x) inserter(x, x,begin())
#define ll long long
#define CLR(x) memset(x, 0, sizeof x)
using namespace std;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int maxn = 1e6 + 10;
const int maxv = 1e3 + 10;
const double eps = 1e-9;

char buf[maxv];
int n;
bool dp[105][55][305][2];
int main() {
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
//  freopen("out.txt","w",stdout);
#endif
    while(scanf("%s", buf + 1) != EOF) { //1代表正方向,0代表反方向
        int len = strlen(buf + 1);
        scanf("%d", &n);
        CLR(dp);
//      puts(buf+1);
        dp[0][0][150][0] = true;
        for(int i = 1; i <= len; i++) {
            for(int j = 0; j <= n; j++) {
                for(int k = 1; k <= 299; k++) {
                    if(buf[i] == 'T') {
                        for(int l = j; l >= 0; l -= 2)
                            dp[i][j][k][1] |= dp[i-1][l][k][0];
                        for(int l = j - 1; l >= 0; l -= 2)
                            dp[i][j][k][1] |= dp[i-1][l][k-1][1];

                        for(int l = j; l >= 0; l -= 2)
                            dp[i][j][k][0] |= dp[i-1][l][k][1];
                        for(int l = j - 1; l >= 0; l -= 2)
                            dp[i][j][k][0] |= dp[i-1][l][k+1][0];
                    }
                    else {
                        for(int l = j; l >= 0; l -= 2)
                            dp[i][j][k][1] |= dp[i-1][l][k-1][1];
                        for(int l = j - 1; l >= 0; l -= 2)
                            dp[i][j][k][1] |= dp[i-1][l][k][0];

                        for(int l = j; l >= 0; l -= 2)
                            dp[i][j][k][0] |= dp[i-1][l][k+1][0];
                        for(int l = j - 1; l >= 0; l -= 2)
                            dp[i][j][k][0] |= dp[i-1][l][k][1];
                    }
                }
            }
        }
        int ans = 0;
        for(int k = 1; k <= 299; k++) {
            for(int l = 0; l <= 1; l++) {
                if(dp[len][n][k][l]) {
//                  printf("%d %d\n", k, l);
                    ans = max(ans, abs(k - 150));
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值