Portal1

https://www.luogu.org/problemnew/show/U41569

题目背景

Agent获取资源有很多种方式,HACK就是其中的一中,侵入Portal可以获得很多有用的资源。ENLIGHTENED总部因为参加XM大战,只剩下一点点可用资源了,所以ENLIGHTENED行动指挥想要进行HACK活动,尽量增加库存。

题目描述

地图上有N个可以被HACKPortal,编号为1~N。HACK第iii号Portal需要时间T[i]秒,可以HACK出C[i]库存的资源。可是只有有能量的Portal才可以HACK出资源。第iii号Portal在第D[i]秒时,能量就会消失殆尽。ENLIGHTEDED想知道,最多可以增加多少库存,并且按编号小到大输出需要HACKPortal的编号。

输入输出格式

输入格式:

第一行输入一个整数N

下接N行每行3个整数,T[i],D[i],C[i]

输出格式:

输出第一行为一个整数,最多可以增加多少库存。

第二行为一个整数,代表需要HACK多少个Portal

第三行按编号小到大输出需要HACKPortal的编号,若有多种HACK的方案输出其中一种即可。

输入输出样例

输入样例#1: 复制

3
5 6 5
1 8 2
2 7 3

输出样例#1: 复制

7
2
1 2

说明

对于20%20\%20%的数据 N≤5,T[i],C[i]≤5,D[i]≤10N\leq 5,T[i],C[i] \leq 5,D[i] \leq 10N≤5,T[i],C[i]≤5,D[i]≤10

对于40%40\%40%的数据 N≤20,T[i],C[i]≤10,D[i]≤100N\leq 20,T[i],C[i] \leq 10,D[i] \leq 100N≤20,T[i],C[i]≤10,D[i]≤100

对于60%60\%60%的数据 N≤50,T[i],C[i]≤15,D[i]≤1000N\leq 50,T[i],C[i] \leq 15,D[i] \leq 1000N≤50,T[i],C[i]≤15,D[i]≤1000

对于100\%的数据 N\leq 100,1 \leq T[i] \leq 20,C[i] \leq 20,1 \leq D[i] \leq 2000

这题我们可以用贪心的方法来解答,我们首先把所有的PortalD[i]为关键字从小到大排序,然后背包判断一下可不可以取,算出个可以取的最大库存,然后倒叙取物品,这样就可以保证时间不会超过消失值,而取到价格库存最大的资源。

#include<iostream>
#include<algorithm>
#define f(i,l,r) for(i=(l);i<=(r);i++)
#define ff(i,r,l) for(i=(r);i>=(l);i--)
using namespace std;
const int MAXN=105,MAXM=2005;
int f[MAXM],v[MAXN][MAXM];
int n;
int q[MAXN];
struct Node{
	int id,t,d,c;
	int st;
	bool operator < (const Node& x)const{
		return d<x.d;
	}
}a[MAXN];
int main()
{
	int i,j,k,ans=0;
	cin>>n;
	f(i,1,n){
		cin>>a[i].t>>a[i].d>>a[i].c;
		a[i].st=a[i].d-a[i].t;
		a[i].id=i;
	}
	sort(a+1,a+1+n);
	f(i,1,n){
		ff(j,a[i].d-1,a[i].t){
			if(f[j]<f[j-a[i].t]+a[i].c){
				f[j]=f[j-a[i].t]+a[i].c;
				v[i][j]=1;
			}
		}
	}
	f(i,1,a[n].d){
		if(f[ans]<f[i]) ans=i;
	}
	cout<<f[ans]<<endl;
	ff(i,n,1){
		if(v[i][ans]){
			q[++q[0]]=a[i].id;
			ans-=a[i].t;
		}
	}
	cout<<q[0]<<endl;
	ff(i,q[0],2){
		cout<<q[i]<<' ';
	}
	cout<<q[1]<<endl;
	return 0;
}

爆搜写法。

#include<iostream>
#include<algorithm>
#define f(i,l,r) for(i=(l);i<=(r);i++)
using namespace std;
const int MAXN=105;
int n;
struct Node{
	int t,d,c,id;
	bool operator < (const Node& x)const{
		return d<x.d;
	}
}a[MAXN];
int opt[MAXN],sum[MAXN],tmp[MAXN];
int ans,num;
void dfs(int cur,int tim,int val)
{
	int i,j;
	int flag=1;
	if(val+sum[n]-sum[cur]<=ans)  return;   //最优性剪枝
	 f(i,cur+1,n){
	 	if(tim+a[i].t<a[i].d){
	 		flag=0;
	 		num++;
	 		tmp[num]=a[i].id;
	 		dfs(i,tim+a[i].t,val+a[i].c);
	 		num--;
	 	}
	 }
	 if(flag&&ans<val){
	 	ans=val;
	 	opt[0]=num;
	 	f(i,1,num){
	 		opt[i]=tmp[i];
		 }
	 }
}
int main()
{
	int i,j;
	cin>>n;
	f(i,1,n){
		cin>>a[i].t>>a[i].d>>a[i].c;
		a[i].id=i;
	}
	sort(a+1,a+1+n);
	f(i,1,n) sum[i]=sum[i-1]+a[i].c;
	dfs(0,0,0);
	cout<<ans<<endl<<opt[0]<<endl;
	f(i,1,opt[0]-1){
		cout<<opt[i]<<' ';
	}
	cout<<opt[opt[0]]<<endl;
	return 0;
	
}

猜你喜欢

转载自blog.csdn.net/MrTinTin/article/details/83044883