[DP]トピック - チェス盤

トピック:https://www.luogu.org/problem/P1436

タイトル説明

次のように8×8のチェッカーボードが分類される:元の長方形の市松模様の部分を切断し、残りの部分は長方形の基板であり、その後分割の残りの2つの部分は、そうし続けるようにカット(N-1)時間後に、n個のブロック矩形ボードの最後に残った長方形の市松模様の合計と一緒。(各カットは、チェス盤の側面に沿って行うことができます)

基板上の各セルは、その合計スコアに含まれる各グリッド矩形ボードのスコアを元のスコアを有します。今、我々は、長方形の基板のn個のブロックに上記の規則によってチェスボードする必要があり、最小二乗和のうち、各長方形のボード。

正方形の最小合計を取得し、ボード・プログラミングとnをお願いします。

入力形式

最初の整数n(1 <N <15)を行います。

2、非負整数100を行うために8時間毎行目にライン9は、基板の対応するセルの値を表します。各隣接する行は、二つの数字の間のスペースで区切られました。

出力フォーマット

二乗和のための数だけ、。

  典型的なDPのタイトルは、アイデアは、私たちは各長方形のため、私たちは考えるの左上隅(a、b)は、右下隅(C、D)矩形を記述するために(A、B、C、D)を使用し、非常に簡単です垂直に切断することが次の目標として、その二つのうちの一つを検討するためにあらゆる時間を削減し、バックカットバックや横に切ります。

  最適化:説明和[I]、[J](1,1、i、j)の領域、および除外を求めた矩形領域。

コードの場合:

 

 1 #include<iostream>
 2 #include<cstdio> 
 3 #include<cmath>
 4 using namespace std;
 5 const int inf=1e9;
 6 int n;
 7 int ma[20][20];
 8 int sum[20][20];
 9 int dp[20][20][20][20][20];
10 int cal(int a,int b,int c,int d){
11     return sum[c][d]+sum[a-1][b-1]-sum[c][b-1]-sum[a-1][d];
12 }
13 int main(){
14     scanf("%d",&n);
15     for(int i=1;i<=8;i++){
16         for(int j=1;j<=8;j++){
17             scanf("%d",&ma[i][j]);
18             sum[i][j]=sum[i-1][j]+sum[i][j-1]+ma[i][j]-sum[i-1][j-1];
19         }
20     }
21     for(int a=1;a<=8;a++){
22         for(int b=1;b<=8;b++){
23             for(int c=a;c<=8;c++){
24                 for(int d=b;d<=8;d++){
25                     dp[a][b][c][d][0]+=cal(a,b,c,d);
26                     dp[a][b][c][d][0]*=dp[a][b][c][d][0];
27                 }
28             }
29         }
30     }
31     for(int t=1;t<n;t++)
32     for(int a=1;a<=8;a++){
33         for(int b=1;b<=8;b++){
34             for(int c=a;c<=8;c++){
35                 for(int d=b;d<=8;d++){
36                     int q=inf;
37                     for(int y=b;y<d;y++){
38                         q=min(q,min(dp[a][b][c][y][0]+dp[a][y+1][c][d][t-1],dp[a][y+1][c][d][0]+dp[a][b][c][y][t-1]));
39                     }
40                     for(int x=a;x<c;x++){
41                         q=min(q,min(dp[x+1][b][c][d][0]+dp[a][b][x][d][t-1],dp[x+1][b][c][d][t-1]+dp[a][b][x][d][0]));//这两句容易错,注意考虑切入点与区间关系
42                     }
43                     dp[a][b][c][d][t]=q;
44                 }
45             }
46         }
47     }
48 //     for(int i=1;i<=8;i++){
49 //        for(int j=1;j<=8;j++){
50 //            cout<<sum[i][j]<<" ";
51 //        }
52 //        cout<<endl;
53 //    }
54     cout<<dp[1][1][8][8][n-1]<<endl;
55     return 0;
56 } 

 

おすすめ

転載: www.cnblogs.com/Nelson992770019/p/11247692.html