版权声明:欢迎转载欢迎评论! https://blog.csdn.net/rabbit_ZAR/article/details/82989548
题目:导弹防御
Country A 与B是敌对国家,它们正在一场战争中互相发射导弹。
A国共发射了N枚导弹,其中第i枚的发射时间为Ta_i,花费Tac_i的时间飞到B国,并可对B国造成Da_i点损害。
B国共发射了M枚导弹,其中第i枚的发射时间为Tb_i,花费Tbc_i的时间飞到A国,并可对A国造成Db_i点伤害。
不过,两国都有一套导弹防御系统,A国的导弹防御系统可以在某个连续TA的时间段内开启(其它时间关闭),
B国的导弹系统可以在某个连续TB的时间段内开启(其它时间关闭)。
当拦截系统开启时,所有到达该国的导弹会立即调转方向按照原本的速度飞向对面国家;
当拦截系统关闭时,导弹会对该国造成损害(拦截系统在时间段端点处,即恰好开启和关闭时也被认为是开启的)。
现在A国的情报部门探听到B国将于时刻X开启导弹系统(在时刻X+TB关闭)。
作为A国的总统,请你决定何时开启本国的导弹系统,可以使受到的损害最小。
思路:
——来自LYD
A 5 9
B 3 7 11
A 11
B 6 16
A 4 10
B 1 7 13
A 4 12
B 0 8 16
A: x发射,飞行y,伤害z
x+y < X 第一次飞到B B没开着拦截 炸B
x+y > X+TB 炸B
x+2*y 需要A开
x+3*y > X+TB 炸B
x+4*y 需要A开
x+5*y
(2k+1) > (X+TB-x)/y 求k最小值
2kmin+1 = (X+TB-x)/y 下取整 + 1
A:[x+2,x+2k*y]
A至少需要在哪个时间段
-> A开启系统的时间的范围
[5,9] 10 -> [5,5] +10
[11,11] 7 [7,11] +7
[4,10] 2 x
[4,12] 8 x
t t+TA
N+M个区间(每个区间有一个价值)
放一个点,让这个点属于的区间价值和最大
1. 线段树,求全局最大值
2. 差分,排序,扫描
5 +10 10
6 -10 0
7 +7 7
12 -7 0
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 10000
#define maxm 100000000
#define read(x) scanf("%d",&x)
struct Node {
int t,tc,d;
Node(){}
Node(int tt,int dd) {
t=tt,d=dd;
}
bool operator < (const Node& oth) const {
return t<oth.t||(t==oth.t&&d>oth.d);
}
};
int TA,TB,X;
int n,m;
Node a[maxn+5],b[maxn+5];
vector<Node> vec;
bool readin() {
if(-1==read(TA)) return false;
read(TB);
read(X);
read(n),read(m);
for(int i=1;i<=n;i++) {
read(a[i].t),read(a[i].tc),read(a[i].d);
}
for(int i=1;i<=m;i++) {
read(b[i].t),read(b[i].tc),read(b[i].d);
}
return true;
}
int main() {
while(readin()) {
vec.clear();
int tot=0;
for(int i=1;i<=n;i++) {
int l=a[i].t+a[i].tc,r=a[i].t+a[i].tc;
if(l<X||X+TB<r) continue;
tot+=a[i].d;
l+=a[i].tc;
r=l+(X+TB-l+a[i].tc)/(a[i].tc*2)*(a[i].tc*2);
if(r-l>TA) continue;
vec.push_back(Node(l,-a[i].d));
vec.push_back(Node((l-(TA-(r-l))),a[i].d));
}
for(int i=1;i<=m;i++) {
int l=b[i].t+b[i].tc;
int r;
tot+=b[i].d;
if (b[i].t+2*b[i].tc<X) r=b[i].t+b[i].tc;
else if (b[i].t+2*b[i].tc>X+TB) r=b[i].t+b[i].tc;
else r=(X+TB-b[i].t)/(2*b[i].tc)*(2*b[i].tc)+l;
if(r-l>TA) continue;
vec.push_back(Node(l,-b[i].d));
vec.push_back(Node((l-(TA-(r-l))),b[i].d));
}
sort(vec.begin(),vec.end());
int x=0,ans=0;
for(int i=0;i<vec.size();i++) {
Node y=vec[i];
x+=y.d;
ans=max(ans,x);
}
printf("%d\n",tot-ans);
}
return 0;
}