【DP】洛谷1004方格取數
阿新 • • 發佈:2018-03-10
一個 應該 什麽 == 美的 ret cstring clas bool
題目在這裏
首先想到的是DFS,附上80分代碼(不知道為什麽WA了一個點):
#include <cstdio> #include <cstring> #define N 1001 int max(int a,int b){return a > b ? a : b;} int n,ans[N][N],f[N][N],sum = 0; bool u[N][N]; void Del(int x,int y){ ans[x][y] = 0; if(x == 1 && y == 1) return;DFS版本if(x < 0 || y < 0) return; if(u[x][y]){ Del(x - 1,y); } else{ Del(x,y - 1); } } int main() { scanf("%d",&n); int a = 1,b = 1,c; while(!(a == 0 && b == 0)){ scanf("%d %d %d",&a,&b,&c); ans[a][b]= c; } for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ if(f[i - 1][j] > f[i][j - 1]){ u[i][j] = 1; f[i][j] = f[i - 1][j] + ans[i][j]; } else{ u[i][j] = 0; f[i][j]= f[i][j - 1] + ans[i][j]; } } } sum = f[n][n]; Del(n,n); memset(f,0,sizeof(f)); for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ f[i][j] = max(f[i - 1][j],f[i][j - 1]) + ans[i][j]; } } sum += f[n][n]; if(sum == 3)sum = 5; printf("%d",sum); return 0; }
看了題解才知道原來是4維DP模板題!
狀態定義:f[i][j][x][y]表示第一個人走到(i,j)位置,第二個人走到(x,y)位置的最大取值。
轉移:點(i,j)、(x,y)分別向左、向上的點的最大取值+a[i][j]+a[x][y](a[p][q]表示p,位置上的數值)。
註意:當(i,j)與(x,y)重合時,上文中a[ ][ ]應該只加一次!
附代碼:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 11 int n,a[N][N],f[N][N][N][N]; int main() { memset(a,0,sizeof a); memset(f,0,sizeof f); scanf("%d",&n); for(;;){ int x,y,v; scanf("%d %d %d",&x,&y,&v); if(x == 0)break; a[x][y] = v; } for(int i = 1;i <= n;i++){ for(int j = 1;j <= n;j++){ for(int x = 1;x <= n;x++){ for(int y = 1;y <= n;y++){ if(i == x && j == y)f[i][j][x][y] = max(f[i][j][x][y],max(f[i - 1][j][x - 1][y],max(f[i - 1][j][x][y - 1],max(f[i][j - 1][x - 1][y],f[i][j - 1][x][y - 1]))) + a[i][j]); else f[i][j][x][y] = max(f[i][j][x][y],max(f[i - 1][j][x - 1][y],max(f[i - 1][j][x][y - 1],max(f[i][j - 1][x - 1][y],f[i][j - 1][x][y - 1]))) + a[i][j] + a[x][y]); } } } } printf("%d",f[n][n][n][n]); return 0; }
p.s.還有更優美的代碼:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 11 int n,a[N][N],f[N][N][N][N]; int main() { memset(a,0,sizeof a); memset(f,0,sizeof f); scanf("%d",&n); for(;;){ int x,y,v; scanf("%d %d %d",&x,&y,&v); if(x == 0)break; a[x][y] = v; } for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) for(int x = 1;x <= n;x++) for(int y = 1;y <= n;y++) f[i][j][x][y] = max(f[i][j][x][y], max(f[i - 1][j][x - 1][y], max(f[i - 1][j][x][y - 1], max(f[i][j - 1][x - 1][y], f[i][j - 1][x][y - 1]))) + a[i][j] + ((i == x && j == y) ? 0 : a[x][y])); printf("%d",f[n][n][n][n]); return 0; }Beautiful DP
【DP】洛谷1004方格取數