1262:【例9.6】挖地雷

  • 我发现我做动归的题是真的弱
  • 刚看到题的时候脑袋都要炸了
  • 啊,我觉得我要英年早秃了
  • 这道一年前还做过
  • 问题是当时没写注释
  • 理论上来说跟没写过差不多……

分析

  • 在牺牲了无数根头发后,我决定先不考虑输出顺序,研究最多的雷的数量
  • 以下是第一版程序,还算比较好想
  • 乱七八糟的输入什么的都好打,这一版的主要思路是从编号小的往后推,每个联通的都走一遍,存储每个节点的最大结果。
  • 那么就只差输出顺序了
	memset(f,0,sizeof(f));
	for(int i=2;i<=n;i++)
		for(int j=1;j<i;j++)
			if(a[j][i]&&dp[i]<dp[j]+w[i]){
				f[i]=j,dp[i]=dp[j]+w[i];
			}
	//以下是简陋的输出
	int maxn=0;
	for(int i=2;i<=n;i++)
		if(dp[i]>maxn)maxn=dp[i];
	cout<<maxn<<endl;
  • 于是我决定再牺牲几根我的头发,打一个比较麻烦的输出思路
  • 虽然我知道倒着推可能会更好一点,奈何我的发量和即将冒烟的脑袋不允许……
  • 所以完整的输出如下
	//没错因为我不想再开一个数组于是就把w数组废物利用了
	int s=0,k; 
	for(k=maxn;f[k]!=0;k=f[k])//关于为什么用for循环……可能是我脑子短路了
		w[++s]=k;
	cout<<k;
	for(int i=s;i>=1;i--)
		cout<<"-"<<w[i];
	cout<<endl<<dp[maxn]<<endl;

代码

  • 那么把上面的两部分合在一起,就是这道题的完整答案了
#include<bits/stdc++.h>
using namespace std;
int n;
int w[210],f[210],dp[210];
bool a[210][210];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>w[i];
		dp[i]=w[i];
	}
	int x,y;
	while(cin>>x>>y){
		if(x==0&&y==0) break;
		else a[x][y]=1;
	}
	memset(f,0,sizeof(f));
	for(int i=2;i<=n;i++)
		for(int j=1;j<i;j++)
			if(a[j][i]&&dp[i]<dp[j]+w[i]){
				f[i]=j,dp[i]=dp[j]+w[i];
			}
	int maxn=0;
	for(int i=2;i<=n;i++)
		if(dp[i]>dp[maxn])maxn=i;
	int s=0,k; 
	for(k=maxn;f[k]!=0;k=f[k])
		w[++s]=k;
	cout<<k;
	for(int i=s;i>=1;i--)
		cout<<"-"<<w[i];
	cout<<endl<<dp[maxn]<<endl;
	return 0;
}
  • 耶,总算写完了,撒花!✿✿ヽ(°▽°)ノ✿
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值