TC SRM 678 Div2 题解

T1 ThePhantomMenace

题意:
有一些门和一些机器
门的安全系数是该门和每个机器的距离的最小值
问 所有门的安全系数的最大值
题解:
暴力枚举每一个门和机器人
对每个门记录到机器的最小值 m m
在记录出 m m 的值后再更新最大值

#include <bits/stdc++.h>
using namespace std;
const int N=110;
int a[N][N];

class ThePhantomMenace {
public:
    int find(vector <int> doors, vector <int> droids);
};
int ThePhantomMenace::find(vector <int> doors, vector <int> droids) {
    int lenx=doors.size(),leny=droids.size();
    int minn,maxn=0;
    for(int i=0;i<lenx;++i){
     maxn=1000000;
     for(int j=0;j<leny;++j){
        int x=abs(doors[i]-droids[j]);
        minn=min(minn,x);
      }
      maxn=max(minn,maxn);
     }
     return maxn;
}

T2 AttackOfTheClones

题意:
N 件衣服。。一周有 N 天(一件衣服穿一天
在第 x 天穿了 i 衣服那么最早在 x + N 1 天可以继续穿
给你一开始穿的顺序和结束时穿的顺序 问最少几周可以完成

题解:
暴力。。
对于每一件衣服 i
在开始时 i F i 位置上
结束时 i L i 位置上
如果

  • F i < L i 那么两周时间必定可以到达
  • F i == L i 一周
  • F i > L i 那么最快 到达的时间为 F i L i + 1

下面的代码 O ( N 2 )

#include <bits/stdc++.h>
using namespace std;

class AttackOfTheClones {
public:
    int count(vector <int> firstWeek, vector <int> lastWeek);
};
int AttackOfTheClones::count(vector <int> firstWeek, vector <int> lastWeek) {
    int len=firstWeek.size();
    for(int i=0;i<len;++i){
        for(int j=0;j<i;++j){
            if(firstWeek[i]==lastWeek[j]){
                int ans=i-j+1;
                maxn=max(maxn,ans);
            }
       }
    }
    return maxn;
}

开个桶存一下可以 O ( n )

#include <bits/stdc++.h>
using namespace std;
const int N=2510;
int a[N],b[N];

class AttackOfTheClones {
public:
    int count(vector <int> firstWeek, vector <int> lastWeek);
};
int AttackOfTheClones::count(vector <int> firstWeek, vector <int> lastWeek) {
    int len=firstWeek.size(),maxn=0;
    for(int i=0;i<len;++i){
        a[firstWeek[i]]=i+1,b[lastWeek[i]]=i+1;
    }
    for(int i=0;i<len;++i){
        int ans=a[firstWeek[i]]-b[firstWeek[i]];
        maxn=max(maxn,ans);
    }
    return maxn;
}

T3 RevengeOfTheSith

题意:
可以将题意转化为
一段区间 被一些点分割成了几个区间
然后最多移动 T 个点 每两个点之间的距离 d i s 如果大于 D 值就加上 ( D d i s ) 2
返回那个值
题解:
DP
d p [ i ] [ j ] 表示第 i 个位置不动 移动 j 处的最小值
可以贪心得出 移动时 使区间越平均越好

dp[i+k+1][j+k]=min(dp[i+k+1][j+k],dp[i][j]+work(qx[i+k+1]-qx[i],k+1,D));
#include <bits/stdc++.h>
using namespace std;
const int N=55;
int qx[N],dp[N][N];

class RevengeOfTheSith {
public:
    int move(vector <int> steps, int T, int D);
};

int js(int x){
    return x*x;
}

int work(int L,int k,int D){        //将长度平均分
    int res=L/k,ans=0;
    if(res+1>D) ans+=(L%k)*js(res-D+1);
    if(res>D) ans+=(k-L%k)*js(res-D);
    return ans;
}

int RevengeOfTheSith::move(vector <int> steps, int T, int D){
    int len=steps.size();
    memset(dp,0x3f,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=len;++i){        //前缀和
        qx[i]=qx[i-1]+steps[i-1];   
    }
    for(int i=0;i<=len;++i){
     for(int j=0;j<=min(i,T);++j)
      for(int k=0;k+j<=T&&i+k+1<=len;++k){
            dp[i+k+1][j+k]=min(dp[i+k+1][j+k],dp[i][j]+work(qx[i+k+1]-qx[i],k+1,D));
        }
    }
    return dp[len][T];
}

emmm
题解写到这里就结束啦
有什么好的方法欢迎在评论区里交流
有什么地方蒟蒻没有讲的很清楚或者讲错了欢迎在评论区里指出

猜你喜欢

转载自blog.csdn.net/LLL_Amazing/article/details/81347683
今日推荐