算法竞赛宝典 动态规划 魔法石矿

【题目描述】魔法石矿(Mine.cpp/c/pas)

为了找到回家的路,张琪曼施展魔法,从高维空间召唤出了一种叫作“读者”的生物,据说“读者”这种生物无所不能,他们可以穿越时空的限制,聆听到历史的声音、巨人的呐喊。但这次“读者”却很严肃地警告她们,从远古起就阴魂不散的天顶星人已冲破封印再次降临到了这个空间,她们若不早做准备,不仅她们所在的这个世界将变成修罗场,连“读者”所在的时空也会受到牵连。最后“读者”交给她们一张藏宝图希望她们能收集足够多的魔法石能量以对抗天顶星人的进攻。已知藏宝图上标有若干个排成一条直线的魔法石矿,每个矿里有一定数量的魔法石,如表所示。

同时每个矿中都有一张说明书,说明在挖完此矿的魔法石后还可继续挖哪些矿,如图所示。

挖矿规则为可以从任何一个矿开始,到任何一个矿结束,同时挖完这个矿中的魔法石之后,可以选择它可继续挖的矿之一继续挖,但只能选择一条。如挖完1矿后,可挖2矿,再挖5矿,6矿,……但只可以向右挖,不能回头向左挖。请问如何挖才能挖出最多的魔法石?

【输入格式】

第一行为一个整数n,表示有n(n≤1000)个矿。第二行为n个整数,表示这n个矿的魔法石数。随后n行表示每个矿挖完后还能再挖哪些矿。

【输出格式】

最多挖出的魔法石数。

【输入样例】

3

1 1 1

1 2 3

2 3

3

【输出样例】

3

//一种类似贪心的思想,这个解法跟标答的不知道有没有一样,因为这是我自己的解法

//这种思考方法就是:先做好预处理,把字符都处理好,便于后面的直接利用

//主要思想:在k节点时,寻找所有能够到达k节点的权值的最大的节点,即可!

#include<iostream>
#include<algorithm>
#include<cstring>
#include<bits/stdc++.h>
const int N=10000+10;
using namespace std;
int dp[N];
int a[N][N];
int mine[N];
bool isnumber(char c)
{
	if(c>='0' && c<='9')
		return true;
	return false;
}                                                           
int main()
{
	int n,x,num,k;
	char c;
	while(cin>>n)
	{
		memset(a,0,sizeof(a));
		for(int i=1; i<=n; i++)
			scanf("%d",&mine[i]);		
		for(int i=1; i<=n; i++)
		{
			scanf("%d",&x);
			k=0;
			do
			{
				num=0;
				while(isnumber(c=getchar()))
					num=num*10+c-'0';
				if(num>0)
						a[num][++a[num][0]]=x;
			}while(c!='\n');
		}
		int ans=0;
		for(int i=1; i<=n; i++)
		{
			int Max=0;
			for(int j=1; j<=a[i][0]; j++)
			{
				Max=max(Max,mine[a[i][j]]);
			}
			mine[i]+=Max;
			ans=max(mine[i],ans);
		}
		printf("%d\n",ans);
	} 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值