概述
题意:
从家到公司,一共 n n n 个红绿灯,一共 n + 1 n+1 n+1 段路。你可以设置每一个红绿灯的开始时间,且每个红绿灯的绿灯时间+红灯时间一致。对于每一种设置,从家出发的时间都任意,因此一定存在一个最坏的情况。先要求输出最坏情况的最小值为多少。 ( 1 ≤ n ≤ 1000 ) (1leq nleq 1000) (1≤n≤1000)
思路:
比赛时无头绪。题意也看了半天才明白。
比赛后知道了解法。答案即为所有路上时间之和加上最大的红灯时间。
但是为什么呢?
其实这是一道构造问题,构造问题的关键在于限制条件。
我们通过调整每个红绿灯的开始时间,使得通过第
i
i
i 个红绿灯之后即可立刻到达第
i
+
1
i+1
i+1 个红绿灯。因此我们最多等待一个红绿灯,接下来即可畅通无阻。因此最坏情况就是加上红绿灯的最大值。
但是这就是答案吗?肯定是。因为无论你怎么设置,由于出发时间任意,我都一定可以让你在某个红绿灯处完整等完这个红绿灯。所以只用等最大的红绿灯就是最后的答案。
总结:
一个构造思维题通过题意的复杂性伪装成了一个或暴力或 D P DP DP 或贪心的问题,迷惑选手。
这题一个很关键的地方在于你可以任意设置红绿灯的开始时间,任意设置!任意设置!任意设置!如果枚举所有的设置必然不可能,因此可以考虑先猜一种比较好求解的设置,然后求最坏情况。
构造问题主要要求就是构造的一定要特殊,好求。将题目初始的一大堆变量全部干掉。
因此总结一下,解决此题,主要思考方法应该是:
- 小数据开始考虑,一个红绿灯,两个,三个…从小数据中找规律。
- 大胆构造特殊情况,将原来的 n n n 个变量全都限制住。在特殊情况下考虑答案,在反证这个构造就是最优答案。
构造思维题继续加油!
代码:
#include <bits/stdc++.h>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const db EPS = 1e-9;
using namespace std;
int n;
db sum;
int main()
{
int _; scanf("%d",&_);
rep(Ca,1,_){
scanf("%d",&n);
sum = 0;
rep(i,1,n+1){
db tp; scanf("%lf",&tp);
sum += tp;
}
db maxn = 0;
rep(i,1,n){
db tp1,tp2; scanf("%lf%lf",&tp1,&tp2);
maxn = max(maxn,tp2);
}
sum += maxn;
printf("Case #%d: %.9fn",Ca,sum);
}
return 0;
}
最后
以上就是安详电灯胆为你收集整理的【Gym-101775 C】Traffic Light【思维】的全部内容,希望文章能够帮你解决【Gym-101775 C】Traffic Light【思维】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复