【20.35%】【codeforces 651D】Image Preview

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya’s telephone contains n photos. Photo number 1 is currently opened on the phone. It is allowed to move left and right to the adjacent photo by swiping finger over the screen. If you swipe left from the first photo, you reach photo n. Similarly, by swiping right from the last photo you reach photo 1. It takes a seconds to swipe from photo to adjacent.

For each photo it is known which orientation is intended for it — horizontal or vertical. Phone is in the vertical orientation and can’t be rotated. It takes b second to change orientation of the photo.

Vasya has T seconds to watch photos. He want to watch as many photos as possible. If Vasya opens the photo for the first time, he spends 1 second to notice all details in it. If photo is in the wrong orientation, he spends b seconds on rotating it before watching it. If Vasya has already opened the photo, he just skips it (so he doesn’t spend any time for watching it or for changing its orientation). It is not allowed to skip unseen photos.

Help Vasya find the maximum number of photos he is able to watch during T seconds.

Input
The first line of the input contains 4 integers n, a, b, T (1 ≤ n ≤ 5·105, 1 ≤ a, b ≤ 1000, 1 ≤ T ≤ 109) — the number of photos, time to move from a photo to adjacent, time to change orientation of a photo and time Vasya can spend for watching photo.

Second line of the input contains a string of length n containing symbols ‘w’ and ‘h’.

If the i-th position of a string contains ‘w’, then the photo i should be seen in the horizontal orientation.

If the i-th position of a string contains ‘h’, then the photo i should be seen in vertical orientation.

Output
Output the only integer, the maximum number of photos Vasya is able to watch during those T seconds.

Examples
input
4 2 3 10
wwhw
output
2
input
5 2 4 13
hhwhh
output
4
input
5 2 4 1000
hhwhh
output
5
input
3 1 100 10
whw
output
0
Note
In the first sample test you can rotate the first photo (3 seconds), watch the first photo (1 seconds), move left (2 second), rotate fourth photo (3 seconds), watch fourth photo (1 second). The whole process takes exactly 10 seconds.

Note that in the last sample test the time is not enough even to watch the first photo, also you can’t skip it.

【题解】

每张图片都有一个状态;
如果是w就要翻转一次花费b时间;
遇到的图片如果之前没看过则一定要看(要翻转则一定要翻转),变为h状态之后才能看->看花费1s;
但是如果是之前看过的可以不看(不花费时间),但是翻的时候还是花费时间a;
可以选择向左或向右翻转;
只能一直往某个方向看到某个位置,然后再看另外一个方向最远能到哪里;
即一直往左到了x,然后再往右到某个位置y;
或者一直往右到了x’,然后再往左到某个位置y’
枚举一端那么另外一端的最远处是固定的了;这个可以用二分搞出来;然后看下最左到最优的差为多少;更新下答案;
枚举先往哪个方向看;(即进行两次二分);
二分的边界注意一下就好;
枚举的时候预处理出了正向和反向到某个点的前缀和;
方便快速判断某个位置是否可行。

#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#define LL long long

using namespace std;

const int MAXN = 1e6;
const int dx[5] = {0,1,-1,0,0};
const int dy[5] = {0,0,0,-1,1};

int n,a,b,T;
string s;
char t;
int zheng[MAXN],fan[MAXN];

void input_LL(LL &r)
{
    r = 0;
    char t = getchar();
    while (!isdigit(t)) t = getchar();
    LL sign = 1;
    if (t == '-')sign = -1;
    while (!isdigit(t)) t = getchar();
    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    r = r*sign;
}

void input_int(int &r)
{
    r = 0;
    char t = getchar();
    while (!isdigit(t)) t = getchar();
    int sign = 1;
    if (t == '-')sign = -1;
    while (!isdigit(t)) t = getchar();
    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    r = r*sign;
}


int main()
{
    //freopen("F:\rush.txt", "r", stdin);
    input_int(n);input_int(a);input_int(b);input_int(T);
    t = getchar();
    T--;
    if (t=='w')
        T-=b;
    if (T <0)
    {
        puts("0");
        return 0;
    }

    cin >> s;
    int len = s.size();
    string temp = s;
    s = " "+s;
    for (int i = 1;i <= len;i++)
    {
        zheng[i] = zheng[i-1]+a+1;
        if (s[i]=='w')
            zheng[i]+=b;
    }

    s = temp;
    reverse(s.begin(),s.end());
    s = " "+s;
    for (int i = 1;i <= len;i++)
    {
        fan[i] = fan[i-1]+a+1;
        if (s[i] == 'w')
            fan[i]+=b;
    }

    //先向左;
    int ans = 0;
    for (int i = 1;i <= n-1;i++)
    {
        if (fan[i]>T)
            break;
        int l = 1,r = n-1-i,tans=0;
        while (l <= r)
        {
            int mid = (l+r)>>1;
            if (zheng[mid]+fan[i]+i*a<=T)
                l = mid+1,tans = mid;
            else
                r = mid-1;
        }
        ans = max(ans,i+tans);
    }

    //向右
    for (int i = 1;i <= n-1;i++)
    {
        if (zheng[i]>T)
            break;
        int l = 0,r = n-1-i,tans =0;
        while (l <= r)
        {
            int mid = (l+r)>>1;
            if (fan[mid]+zheng[i]+i*a<=T)
                l = mid+1,tans = mid;
            else
                r = mid-1;
        }
        ans = max(ans,i+tans);
    }

    printf("%d
",ans+1);
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7632115.html