Everything that kills me makes me feel alive.

P4766 [CERC2014]Outer space invaders 题解

题目链接

小小讲一讲吧,写篇题解。

条件

  • n 非常小,大概 n3 能过。

  • 有编号,时间,距离三个要素。

  • 时间很大,不可能直接作为数组的两维。

思路

出于对上述条件的考虑,一位大佬思考过后决定使用区间dp,并教会了我。

  • 用离散化后的时间作为数组的两维。

  • 而后每次枚举时间的时候,找到这在当前时间区间中距离最大的外星人。由于这个外星人必须被杀,且杀完它之后其他外星人都被杀了,所以我们直接考虑它就可以了。

状态转移方程

dpi,j=mink=lidrid(dpi,j,dpi,k1+dpk+1,j+did)

id 为当前区间距离最大的外星人的编号。

code

#include<bits/stdc++.h>
using namespace std;
const int N=750,Inf=11000*300;

template<class T> T read(T &x){
	char c=getchar();bool f=0;x=0;
	while(!isdigit(c)) f|=c=='-',c=getchar();
	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return f?-x:x;
} 

int T,n;
int dp[N][N],tim[N],id[11000];//tim为离散数组,注意数组的大小 
struct node{
	int l,r,d;
}a[N];

int main(){
	read(T);
	while(T--){
		read(n);
		int cnt=0;
		memset(dp,0,sizeof(dp));//初始化重点
		for(int i=1;i<=n;i++) read(a[i].l),read(a[i].r),read(a[i].d),tim[++cnt]=a[i].l,tim[++cnt]=a[i].r;
		sort(tim+1,tim+cnt+1);
		for(int i=1;i<=cnt;i++) id[tim[i]]=i;
		for(int i=1;i<=n;i++) a[i].l=id[a[i].l],a[i].r=id[a[i].r];//离散化
		for(int len=1;len<cnt;len++){
			for(int i=1;i+len<=cnt;i++){
				int j=i+len,now=0;
				dp[i][j]=Inf;//初始化 
				for(int k=1;k<=n;k++){//寻找max
					if(a[k].l>=i&&a[k].r<=j)
					 	if(!now||a[k].d>a[now].d) now=k;
				}
				if(!now) {dp[i][j]=0;continue;}//dp[i][j]=0没有敌人 
				for(int k=a[now].l;k<=a[now].r;k++) dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[now].d);
			}
		}
		printf("%d\n",dp[1][cnt]);
	}
}
/*
1
3
1 4 4
4 7 5
3 4 7
*/
/*
7
*/
posted @   wind_seeker  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
Live2D
欢迎阅读『P4766 [CERC2014]Outer space invaders 题解』
点击右上角即可分享
微信分享提示