3 条题解
-
1
看神犇们都用 DP 做,本蒟蒻还不会 DP ,就只能用学过的最短路算法来做了。(希望能早日像神犇一样学会 DP )
基本思路: 把整个图的每一个点能到达的 个点都使用链式前向星存边,边权就为终点的金币数的相反数(因为是求最长路),然后使用能够处理负权边的 SPFA 算法处理,接着找出图的最后一列的 个点的路径长度的相反数的最大值作为 ,最后输出就可以了。
注意: 需要考虑一下节点数和边数,不要把数组开小了。 还要把二维图转化为一维。
(尽管代码很长,但看了一下,用最短路算的是比 DP 快的。)
下面附上 AC 代码:#include<bits/stdc++.h> using namespace std; struct edge { int to,next,w; }a[150001]; int i,j,n,u,v,w,cnt,ans,m[5][10000],head[50001],dis[50001]; bool vis[50001]; queue<int>q; bool check(int x,int y) { if (x<0||y<0||x>4||y>=n) return false; return true; } void add(int u,int v,int w) { a[++cnt].to=v; a[cnt].next=head[u]; head[u]=cnt; a[cnt].w=-w; return; } int ex(int x,int y) { return x*n+y; } void spfa(int s) { for (int i=1;i<2001;++i) dis[i]=0x3fffffff; dis[s]=0; vis[s]=true; q.push(s); while (!q.empty()) { int u=q.front(); vis[u]=false; q.pop(); for (int i=head[u];i!=0;i=a[i].next) if (dis[a[i].to]>dis[u]+a[i].w) { dis[a[i].to]=dis[u]+a[i].w; if (!vis[a[i].to]) { vis[a[i].to]=true; q.push(a[i].to); } } } return; } int main() { scanf("%d",&n); for (i=0;i<5;++i) for (j=0;j<n;++j) scanf("%d",&m[i][j]); for (i=0;i<5;++i) for (j=0;j<n;++j) { if (check(i-1,j+1)) add(ex(i,j),ex(i-1,j+1),m[i-1][j+1]); if (check(i,j+1)) add(ex(i,j),ex(i,j+1),m[i][j+1]); if (check(i+1,j+1)) add(ex(i,j),ex(i+1,j+1),m[i+1][j+1]); } spfa(ex(2,0)); for (i=0;i<5;++i) ans=max(ans,-dis[ex(i,n-1)]); printf("%d",ans); return 0; }
希望明年科技节信息竞赛我能拿特等奖。 -
1
#include<bits/stdc++.h> #define int long long using namespace std; const int N=1e4+5; int n,k,ans; int a[10][N]; int f[10][N]; signed main(){ cin>>n; for(int i=1;i<=5;i++){ for(int j=1;j<=n;j++){ cin>>a[i][j]; } } f[3][1]=a[3][1]; a[1][1]=a[2][1]=a[4][1]=a[5][1]=a[1][2]=a[5][2]=0; for(int i=1;i<=5;i++) f[i][1]=0; for(int i=2;i<=n;i++){ f[1][i]=max(f[1][i-1],f[2][i-1])+a[1][i]; f[5][i]=max(f[5][i-1],f[4][i-1])+a[5][i]; for(int j=2;j<=4;j++){ f[j][i]=max(max(f[j][i-1],f[j-1][i-1]),f[j+1][i-1])+a[j][i]; } } ans=0; for(int i=1;i<=5;i++) ans=max(ans,f[i][n]); cout<<ans; return 0; }
数组开爆了我哭死QAQ
-
0
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e4+5; int a[10][N],dp[10][N]; int n; signed main() { cin>>n; for(int i=1;i<=5;i++) for(int j=1;j<=n;j++) cin>>a[i][j],dp[i][j]=a[i][j]; dp[1][2]=0; dp[5][2]=0; for(int i=3;i<=n;i++) { for(int j=1;j<=5;j++) { dp[j][i]=dp[j][i]+max(max(dp[j][i-1],dp[j-1][i-1]),dp[j+1][i-1]); } } int ans=0; // for(int i=1;i<=5;i++) // { // for(int j=1;j<=n;j++) // { // cout<<dp[i][j]<<' '; // } // cout<<'\n'; // } for(int i=1;i<=5;i++) ans=max(ans,dp[i][n]); cout<<ans; return 0; }
- 1
信息
- ID
- 950
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 90
- 已通过
- 16
- 上传者