https://www.luogu.org/problemnew/show/U41569
题目背景
Agent
获取资源有很多种方式,HACK
就是其中的一中,侵入Portal
可以获得很多有用的资源。ENLIGHTENED总部
因为参加XM大战
,只剩下一点点可用资源了,所以ENLIGHTENED行动指挥
想要进行HACK
活动,尽量增加库存。
题目描述
地图上有N
个可以被HACK
的Portal
,编号为1~N。HACK
第iii号Portal
需要时间T[i]秒,可以HACK
出C[i]库存的资源。可是只有有能量的Portal
才可以HACK
出资源。第iii号Portal
在第D[i]秒时,能量就会消失殆尽。ENLIGHTEDED
想知道,最多可以增加多少库存,并且按编号小到大输出需要HACK
的Portal
的编号。
输入输出格式
输入格式:
第一行输入一个整数N
下接N行每行3个整数,T[i],D[i],C[i]
输出格式:
输出第一行为一个整数,最多可以增加多少库存。
第二行为一个整数,代表需要HACK
多少个Portal
。
第三行按编号小到大输出需要HACK
的Portal
的编号,若有多种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
这题我们可以用贪心的方法来解答,我们首先把所有的Portal
以为关键字从小到大排序,然后背包判断一下可不可以取,算出个可以取的最大库存,然后倒叙取物品,这样就可以保证时间不会超过消失值,而取到价格库存最大的资源。
#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;
}