Lightoj1156【二分+貪心】

題意:略。
思路:
以爲我這個思路是大衆思路原來不是。。。百度了一下什麼最大流(膜拜熟練應用最大流選手)
二分很顯然對吧,然後我就想二分完DP嘛,好像不行,感覺怎麼搞都是你已經把答案搞出來的感覺,所以二分顯得沒有意義,想想貪心吧~
然後突然一想,其實你想啊,走回來和走過去是一樣的對吧,無非就是有些不能一起走。那麼我們先在起始位置(0)放兩個人,然後一起往前走,首先找一個能走的最遠的無約束位置,如果找不到,就讓他們兩個分開了,這時候只要走小一點,慢慢走,默認第一個人走的比第二個人走的少; 但是會存在當前兩個人位置不一樣的情況,那就按小的位置來找能在一起的位置,不能的話,給小的位置找一個位置,然後就這樣過了,233333333,具體思路自己體會吧~

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<list>
using namespace std;

typedef pair<int,int> PII;
typedef long long LL;

#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1

const double eps = 1e-9;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;

const int Maxn = 1e2 + 10;
int n, d;
bool f[Maxn], vis[Maxn];
int dis[Maxn];
bool Judge(int Max){
    memset(vis, false, sizeof(vis));
    int p1, p2, pos;

    p1 = p2 = 0;
    while(p1 <= n && p2 <= n){
        if(p1 == p2){
            pos = -1;
            for(int i=p1+1;i<=n+1;i++){
                if((dis[i] - dis[p1] <= Max) && (!f[i])) pos = i;
                else break;
            }
            if(pos == -1){
                pos = -1;
                for(int i=p1+1;i<=n+1;i++){
                    if(dis[i] - dis[p1] <= Max && !vis[i]){
                        pos = i;
                        break;
                    }
                }
                if(pos == -1) return false;
                vis[pos] = true;
                p1 = pos;

                pos = -1;
                for(int i=p1+1;i<=n+1;i++){
                    if(dis[i] - dis[p2] <= Max && !vis[i]){
                        pos = i;
                        break;
                    }
                }
                if(pos == -1) return false;
                vis[pos] = true;
                p2 = pos;
            }
            else
            {
                if(pos == n+1) return true;
                p1 = p2 = pos;
            }
        }
        else
        {
            if(p1 > p2) swap(p1, p2);
            pos = -1;
            for(int i=p1+1;i<=n+1;i++){
                if((dis[i] - dis[p1] <= Max) && (!f[i])) pos = i;
            }
            if(pos == -1){
                for(int i=p1+1;i<=n+1;i++){
                    if((dis[i] - dis[p1] <= Max) && (!vis[i]))
                    {
                        pos = i;
                        break;
                    }
                }
                if(pos == -1) return false;
                vis[pos] = true;
                p1 = pos;
            }
            else{
                if(pos == n+1) return true;
                p1 = p2 = pos;
            }
        }
    }
}

void Debug(){
    for(int i=0;i<=n+1;i++)
    printf("%d\n", f[i]);
}

void solve(){
    int Mid;
    int Left = 1, Right = d;
    while(Left < Right){
        Mid = Left + (Right - Left) / 2;
        if(Judge(Mid)) Right = Mid;
        else Left = Mid + 1;
    }
    printf("%d\n", Left);
}


int main(){
    int T, cas = 1;
    char ch;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &d);
        getchar();

        f[0] = false;
        f[n+1] = false;
        dis[0] = 0;
        dis[n+1] = d;

        for(int i=1;i<=n;i++){
            scanf("%c-%d", &ch, &dis[i]);
            getchar();
            if(ch == 'S') f[i] = true;
            else f[i] = false;
        }
//        Debug();
        printf("Case %d: ", cas++);
        solve();
    }
    return 0;
}
發佈了799 篇原創文章 · 獲贊 125 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章