AcWing1027。グリッドアクセス[DP動的計画法] C ++バージョンの問題解決

トピック

N×Nグリッドがあります。いくつかの正方形に正の整数を入力し、他の正方形に数値0を入力します。以下に示すように:

ここに画像の説明を挿入

誰かが図の左上隅のAから開始し、右下隅のポイントBに到達するまで下または右に歩くことができます。

彼が歩く途中で、彼は正方形の数字を取ることができます(それを取った後の正方形は数字0になります)。

この人は、ポイントAからポイントBまで2回歩いています。得られた数の合計が最大になるように、そのようなパスを2つ見つけてください。

入力形式
最初の行は整数Nで、N×Nグリッドグラフを表します。

後続の各行には3つの整数があり、1つ目は行番号、2つ目は列番号、3つ目は行と列に配置された番号です。

行番号と列番号は1から始まります。

「000」の行は終了を意味します。

出力形式
2つのパスで取得された最大の合計を表す整数を出力します。

データ範囲
N≤10
入力例:
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
出力例:
67

アイデア

一度だけ行く:)
f[i,j]から(1,1歩いたすべて(i,j)のパスの最大値がf[i,j]= max(f[i-1,j]+ w[i], f[i-1][j]+ w[i])
2回行くことを意味ます:
f[i1,j1,i2,j2 ](1,1),(1,1)それぞれから歩いたすべて(i1,j1),(i2,j2)のパスの最大値を意味します。
「同じグリッドを繰り返し選択できない」の対処方法は? 2つの場合
のみi1 + j1 == i2 +j2パスのグリッドが重なる可能性
f[k, i1, i2]あります。これは、(1,1),(1,1)別々に移動したすべて(i1,k-i1), (i2,k-i2)のパスの最大値と
k、2つのルートが現在あるグリッドの水平座標と垂直座標の合計意味します。行きます。
k = i1 + j1 = i2+ j2

したがって、状態遷移に相当f[i1][j1][i2][j2]する3次元へ最適化f[k][i1][i2]
[i1][k−i1][i2]k−i2]
ここに画像の説明を挿入
状態方程式を解く:
4種類の動きを考えます。

記事1:次の記事2:次

f[i1-1]][j1][i2-1][j2]==f[k-1][i1-1][i2-1];

第1条:第2条の下で右

f[i1-1][j1][i2][j2-1]==f[k-1][i1-1][i2];

記事1:右記事2:ダウン

f[i1][j1-1][i2-1][j2]==f[k-1][i1][i2-1];

記事1:正しい記事2:正しい

f[i1][j1-1][i2][j2-1]==f[k-1][i1][i2];
ここに画像の説明を挿入

コード

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=15;
int w[N][N];
int f[N*2][N][N];
int main()
{
    
    
    int n;
    cin>>n;
    int a,b,c;
    while(cin>>a>>b>>c,a||b||c) w[a][b]=c;
    for(int k=2;k<=n*2;k++)
      for(int i1=1;i1<=n;i1++)
       for(int i2=1;i2<=n;i2++)
         {
    
    
             int j1=k-i1,j2=k-i2;
             int t=w[i1][j1];
             if(i1!=i2)  t+=w[i2][j2];        //未走到同一格子
             if(i1>=1&&i1<=n&&i2>=1&&i2<=n)   //判断是否在边界内
             {
    
    
                int &x=f[k][i1][i2];
                x=max(x,f[k-1][i1-1][i2-1]+t);
                x=max(x,f[k-1][i1-1][i2]+t);
                x=max(x,f[k-1][i1][i2-1]+t);
                x=max(x,f[k-1][i1][i2]+t);
             }
         }
    cout<<f[n*2][n][n]<<endl;
    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_45629285/article/details/110006371