1. 程式人生 > >【01揹包】#洛谷# P1004 方格取數

【01揹包】#洛谷# P1004 方格取數

方格取數

題目

設有N \times NN×N的方格圖(N \le 9)(N≤9),我們將其中的某些方格中填入正整數,而其他的方格中則放入數字00。如下圖所示(見樣例):

A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 B 某人從圖的左上角的AA點出發,可以向下行走,也可以向右走,直到到達右下角的BB點。在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字00)。 此人從AA點到BB點共走兩次,試找出22條這樣的路徑,使得取得的數之和為最大。

輸入

輸入的第一行為一個整數NN(表示N \times NN×N的方格圖),接下來的每行有三個整數,前兩個表示位置,第三個數為該位置上所放的數。一行單獨的00表示輸入結束。

輸出

只需輸出一個整數,表示22條路徑上取得的最大的和。

輸入樣例

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

解題思路

做這道題我用了01揹包的做法 再把空間複雜度再降到O(n^2) 我們考慮兩個人同時走 所以狀態轉移方程為: f[i][j][k][l]=max(f[i-1][j][k-1][l],f[i-1][j][k][l-1],f[i][j-1][k-1][l],f[i][j-1][k][l-1])+a[i][j]+a[k][l];f[i][j][k][l]=max(f[i−1][j][k−1][l],f[i−1][j][k][l−1],f[i][j−1][k−1][l],f[i][j−1][k][l−1])+a[i][j]+a[k][l] 但這樣要判斷 i=k&&j=l 的情況。

#include<iostream>
#include<cstdio>
using namespace std;
int f[20][20][20][20],a[20][20],n,x,y,z;
int main() 
{
    scanf("%d%d%d%d",&n,&x,&y,&z);
    while(x!=0||y!=0||z!=0)
    {
      a[x][y]=z;
      scanf("%d%d%d",&x,&y,&z);
    }
    for(int i=1;i<=n;i++)
        for
(int j=1;j<=n;j++) for(int k=1;k<=n;k++) for(int l=1;l<=n;l++){ f[i][j][k][l]=max(max(f[i-1][j][k-1][l],f[i-1][j][k][l-1]),max(f[i][j-1][k-1][l],f[i][j-1][k][l-1]))+a[i][j]+a[k][l]; if(i==k&&l==j) f[i][j][k][l]-=a[i][j]; } cout<<f[n][n][n][n]; return 0; }