- 我发现我做动归的题是真的弱
- 刚看到题的时候脑袋都要炸了
- 啊,我觉得我要英年早秃了
- 这道一年前还做过
- 问题是当时没写注释
- 理论上来说跟没写过差不多……
分析
- 在牺牲了无数根头发后,我决定先不考虑输出顺序,研究最多的雷的数量
- 以下是第一版程序,还算比较好想
- 乱七八糟的输入什么的都好打,这一版的主要思路是从编号小的往后推,每个联通的都走一遍,存储每个节点的最大结果。
- 那么就只差输出顺序了
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;
- 于是我决定再牺牲几根我的头发,打一个比较麻烦的输出思路
- 虽然我知道倒着推可能会更好一点,奈何我的发量和即将冒烟的脑袋不允许……
- 所以完整的输出如下
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;
代码
- 那么把上面的两部分合在一起,就是这道题的完整答案了
#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;
}