预处理+条件的维度减少

思维: 3个人的同时满足条件 通过预处理 (每2个人之间的关系) 来达到后面 操作的 O1 复杂度 》》达到降维 的目的(减少时间复杂度);

title:
环岛三人行!    
time limit: 
2s
memory limit: 
128m
description :
舟游两周年啦~Keller决定叫上王浩源和dyp一起去罗德岛游玩!
罗德岛是希腊第四大岛,是爱琴地区文明的起源地之一,景色十分优美~但是由于舟游两周年期间罗德岛十分火爆,游客们水太深,官方担心岛上的各个景点会把握不住,因此出台了一条新的政策:同一个景点在同一时刻只能有一人游玩!其他人想要入内游玩的游客都需要在门口等候。这就意味着他们三个不能一起环岛游玩了。
出行前,Keller已经查好了若干个罗德岛必去景点,这些景点都分布在一条环岛公路上,Keller将他们按照顺时针顺序给每个景点编上了序号1,2,...,n。现在Keller、王浩源、dyp决定跳伞同时着陆到三个不同的景点,然后沿顺时针依次开始他们的环岛旅行,惜时如金的王浩源希望在自己的旅途过程中没有任何时刻需要在门口等待其他人,家财万贯的dyp则动用钞能力把岛上的其他游客都赶走了!
现在岛上只有他们三个游客,已知每个人在各个景点都需要消耗固定的时间游玩,两两景点间的乘车中转时间固定,现在请你帮助他们找到各自合适的着陆景点编号,使得他们三人在玩完全部n个景点过程中不需要等待。

input :
输入第一行包含一个整数n,表示一共有n个景点(n<=400)
输入第二行包含n个整数,表示从第i个到第i+1个景点的中转耗时di(第n个整数表示从第n个景点到第1个景点的耗时)
接下来三行每行n个整数,分别表示Keller、王浩源、dyp在第i个景点的游玩时间ti

output:
  输出包含三个整数,分别为Keller、王浩源、dyp的着陆景点编号。若方案不存在,输出"impossible",若存在多个方案,输出字典序最小的方案。
sample input 1:
6 
1 1 1 1 1 1 
2 1 3 2 3 1 
8 7 4 9 7 2 
7 6 2 9 2 1
sample output 1:
1 5 6
sample input 2:
4 
1 1 1 1 
1 1 1 1 
10 3 2 1 
4 2 5 1
sample output 2:
impossible
hint:
 保证输入的数据大小均不超过10^6
source :
Keller
    
View topic
#include<bits/stdc++.h>
using namespace std;
const int maxn = 400+10;
const int maxp =4;
int c[maxn];
int f[maxp][maxp][maxn][maxn];
int d[maxp][maxn];
int n;
void init(int a,int b){
    int sta[maxn],stb[maxn];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            memset(sta,0,sizeof(sta));
            memset(stb,0,sizeof(stb));
            int anow=i,bnow=j,cnt=1;
            while(cnt<n){
                sta[(anow)%n+1]=sta[anow]+d[a][anow]+c[anow];
                stb[(bnow)%n+1]=stb[bnow]+d[b][bnow]+c[bnow];
                anow=(anow)%n+1;
                bnow=(bnow)%n+1;
                cnt++;
            }
            int isok=1;
            for(int t=1;t<=n;t++){
                if(sta[t]>=stb[t] && sta[t]<stb[t]+d[b][t]){
                    isok=0;   
                    break;
                }
                if(sta[t]<=stb[t] && stb[t]<sta[t]+d[a][t]){
                    isok=0;   
                    break;
                }
            }
            if(isok){
                f[a][b][i][j]=1;     
            }
        }
    }
    return ;
}
 
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d",&c[i]);    
    }
    for(int i=1;i<=3;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&d[i][j]);
        }
    }
    init(1,2);
    init(1,3);
    init(2,3);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                if(f[1][2][i][j] && f[1][3][i][k] && f[2][3][j][k]){
                    cout<<i<<" "<<j<<" "<<k;
                    return 0;
                }
            }
        }
    }
    cout<<"impossible";
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Lamboofhome/p/15618363.html