トピックリンク
分析タイトル
ここではご紹介開けないでください\(O2 \を)方法
この問題の良いプッシュDP方程式:
\(F [X 1] [Y_1] [X_2] [Y_2] =分([X 1] [Y_1] [X_2] [Y_2]、iは+ [X 1] [Y_1] [I] [Y_2] + Fの[F F 1] [Y_1] [X_2] [Y_2] + S [X 1] [Y_1] [X_2] [Y_2])\)
そして、:
\(F [X_1] [Y_1] [X_2] [Y_2] =分(F [X_1] [Y_1] [X_2] [Y_2]、F [X_1] [Y_1] [X_2] [I] + F [X_1] [I + 1] [X_2] [Y_2] + S [X_1] [Y_1] [X_2] [Y_2])\)
コードを見て意味の特定の配列を理解します
\ -そして、メモリ検索作る(TLE \) A
私たちは、アクセスの4次元配列が非常に遅いことがわかったので、あなたは四次元にハッシュする同様の方法を使用することができます
そして、カード上の高いです後
コード
#include <stdio.h>
using namespace std;
template <typename T> inline void Read(T &t)
{
int c=getchar(),f=0;
for (;c<'0'||c>'9';c=getchar()) f=(c=='-');
for (t=0;c>='0'&&c<='9';c=getchar()) t=(t<<3)+(t<<1)+(c^48);
if (f) t=-t;
}
const int N=55,t[]={1,55,3025,166375,9150625};
int n,m,s[N][N];
int dp[N*N*N*N];
inline int min(int a, int b) {return a<b?a:b;}
int dfs(int x, int y, int _x, int _y)
{
int a=x*t[3]+y*t[2]+_x*t[1]+_y*t[0];
if (dp[a]) return dp[a];
if (x==_x&&y==_y) return 0;
dp[a]=0x7fffffff;
for (int i=x;i<_x;i++)
dp[a]=min(dp[a],dfs(x,y,i,_y)+dfs(i+1,y,_x,_y));
for (int i=y;i<_y;i++)
dp[a]=min(dp[a],dfs(x,y,_x,i)+dfs(x,i+1,_x,_y));
return dp[a]+=s[_x][_y]-s[x-1][_y]-s[_x][y-1]+s[x-1][y-1];
}
int main()
{
Read(n),Read(m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
Read(s[i][j]),s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
printf("%d\n",dfs(1,1,n,m));
return 0;
}