资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
逗志芃励志要成为强力党,所以他将身上所以的技能点都洗掉了重新学技能。现在我们可以了解到,每个技能都有一个前提技能,只有学完了前提技能才能学习当前的技能(有一个最根本的技能不需要前提技能)。学习每个技能要消耗一个技能点,然后可以获得这个技能的威力值。由于逗志芃要陪妹子,所以他希望你教他如何点技能使得威力值最大从而成为强力党。
输入格式
第一行两个数n,m表示有n个技能和m个技能点。第二行有n个数,第i个数表示第i个技能的威力值。
之后的n-1行,每行两个数x,y,表示y技能的前提技能是x,也就是说先学第x个技能才能学弟y个技能。
输出格式
一个数,最大的威力值。
样例输入
3 2
1 10 20
1 2
1 3
样例输出
21
数据规模和约定
0<n,m<=200, 技能的威力值不超过200。
#include<iostream>
using namespace std;
const int N=205;
int n,m;
int data[N];
int fro[N];
bool flag[N];
int ans;
void dfs(int x,int score){
if(x==m){
ans=max(ans,score);
return ;
}
for(int i=1;i<=n;i++){
//如果当前技能点没有被学过 且 前面的技能已经学过或这个技能点不需要前提技能
if(!flag[i]&&(flag[fro[i]]||fro[i]==0)){
flag[i]=true;
dfs(x+1,score+data[i]);
flag[i]=false;
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&data[i]);
}
for(int i=0;i<n-1;i++){
int a,b;
scanf("%d%d",&a,&b);
fro[b]=a;
}
dfs(0,0);
printf("%d\n",ans);
return 0;
}
思路:dfs。但是运行超时。所以用树形dp: