Acwing1027.方格取数

79 阅读1分钟

1027. 方格取数 - AcWing

  • k=i1+j1=i2+j2k=i1+j1=i2+j2: 两个小朋友同时走, 每个人走的步数和是一样的.
  • f[i1,j1,i2,j2]f[i1,j1,i2,j2]: 由摘花生问题可以推广出从(1,1),(1,1)走到(i1,j1),(i2,j2)(1,1),(1,1)走到(i1,j1),(i2,j2)能获得的最大花生数目. 由上面的两条性质可以推出三维的状态转移方程f[i1,ki1,i2,ki2]f[k,i1,i2]f[i1,k−i1,i2,k−i2]→f[k,i1,i2]:两个小朋友同时走k步,从(1,1),(1,1)走到(i1,j1),(i2,j2)(1,1),(1,1)走到(i1,j1),(i2,j2)能获得的最大花生数目.
  • 0:代表小朋友要到下边一个格子
  • 1:代表小朋友要到右边一个格子
  • 难点:∀∀格子仅能取一次. 两个小朋友在同一个格子→必有i1==i2,j1==j2i1==i2,j1==j2,而后边状态限制同时走,所以当i1==i2i1==i2时便走到同一格. image.png

C++代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 15;
int w[N][N];
int n;
int f[N*2][N][N];
int main(){
    cin>>n;
    int a,b,c;
    while(cin>>a>>b>>c,a||b||c)w[a][b]=c;
    for(int k=2;k<=n+n;k++){
        for(int i1=1;i1<=n;i1++){
            for(int i2=1;i2<=n;i2++){
                int j1=k-i1,j2=k-i2;
                if(j1>=1&&j1<=n&&j2>=1&&j2<=n){
                    int t=w[i1][j1];
                    if(i1!=i2)t+=w[i2][j2];
                    
                    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+n][n][n]<<endl;
    
    return 0;
}

Go代码

package main

import (
	"bufio"
	"fmt"
	"os"
)

var in = bufio.NewReader(os.Stdin)
var out = bufio.NewWriter(os.Stdout)

const N = 15

var w [N][N]int
var f [N * 2][N][N]int
var n int

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func main() {
	defer out.Flush()
	fmt.Fscan(in, &n)

	var (
		a, b, c int
	)
	for {
		fmt.Fscan(in, &a, &b, &c)
		if a == 0 && b == 0 && c == 0 {
			break
		}
		w[a][b] = c
	}
	for k := 2; k <= n+n; k++ {
		for i1 := 1; i1 <= n; i1++ {
			for i2 := 1; i2 <= n; i2++ {
				var j1 int = k - i1
				var j2 int = k - i2
				if j1 >= 1 && j1 <= n && j2 >= 1 && j2 <= n {
					x := w[i1][j1]
					if i1 != i2 {
						x += w[i2][j2]
					}
					f[k][i1][i2] = max(f[k][i1][i2], f[k-1][i1-1][i2-1]+x)
					f[k][i1][i2] = max(f[k][i1][i2], f[k-1][i1-1][i2]+x)
					f[k][i1][i2] = max(f[k][i1][i2], f[k-1][i1][i2-1]+x)
					f[k][i1][i2] = max(f[k][i1][i2], f[k-1][i1][i2]+x)
				}
			}
		}
	}
	fmt.Fprintln(out,f[n+n][n][n])
}