【動態規劃】Vijos P1143 三取方格數(NOIP2000提高組)
阿新 • • 發佈:2019-01-22
題目連結:
題目大意:
NxN的矩陣,每個值只能取一次,從(1,1)走到(n,n)走三次能取得的最大值。
題目思路:
【動態規劃】
f[x1][y1][x2][x3]表示第一次走x1,y1,相同步數下第二次走x2,y2,第三次走x3,y3的最大值。
因為步數一樣y2,y3可以直接求出來。
// //by coolxxx //#include<bits/stdc++.h> #include<iostream> #include<algorithm> #include<string> #include<iomanip> #include<map> #include<memory.h> #include<time.h> #include<stdio.h> #include<stdlib.h> #include<string.h> //#include<stdbool.h> #include<math.h> #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define abs(a) ((a)>0?(a):(-(a))) #define lowbit(a) (a&(-a)) #define sqr(a) ((a)*(a)) #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define eps (1e-8) #define J 10 #define MAX 0x7f7f7f7f #define PI 3.14159265358979323 #define N 24 using namespace std; typedef long long LL; int cas,cass; int n,m,lll,ans; int a[N][N]; int f[N][N][N][N]; int main() { #ifndef ONLINE_JUDGE // freopen("1.txt","r",stdin); // freopen("2.txt","w",stdout); #endif int i,j,x1,y1,x2,y2,x3,y3; // for(scanf("%d",&cas);cas;cas--) // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) while(~scanf("%d",&n)) // while(~scanf("%d",&n)) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) scanf("%d",&a[i][j]); } for(x1=1;x1<=n;x1++) { for(y1=1;y1<=n;y1++) { for(x2=1;x2<=x1;x2++) { for(x3=1;x3<=x1;x3++) { y2=x1+y1-x2;y3=x1+y1-x3; f[x1][y1][x2][x3]=max( max(max(f[x1-1][y1][x2][x3],f[x1-1][y1][x2][x3-1]), max(f[x1-1][y1][x2-1][x3],f[x1-1][y1][x2-1][x3-1])), max(max(f[x1][y1-1][x2][x3],f[x1][y1-1][x2][x3-1]), max(f[x1][y1-1][x2-1][x3],f[x1][y1-1][x2-1][x3-1])))+a[x1][y1]; if(x1!=x2 && y1!=y2)f[x1][y1][x2][x3]+=a[x2][y2]; if(x1!=x2 && y1!=y2 && x1!=x3 && y1!=y3 && x2!=x3 && y2!=y3)f[x1][y1][x2][x3]+=a[x3][y3]; } } } } printf("%d\n",f[n][n][n][n]); } return 0; } /* // // */