标签:
HDU 5492(dp
题目:一个数字矩阵,要求找到一条路径使得经过的数字的方差最小.
思路:稍微把式子变换一下,状态是走到当前格子和为k时最小平方和.
/* * @author: Cwind */ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0) #define pb push_back #define PB pop_back #define bk back() #define fs first #define se second #define sq(x) (x)*(x) #define eps (1e-6) #define IINF (1<<29) #define LINF (1ll<<59) #define INF (1000000000) #define FINF (1e3) typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> P; const int maxsum=1900; const int maxn=40; int T,n,m; int grid[maxn][maxn]; int dp[maxn][maxn][maxsum]; int h[maxn][maxn]; int pos[maxn][maxn][maxsum]; int inf; int cas=0; int main(){ freopen("/home/files/CppFiles/in","r",stdin); //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); memset(dp,0x3f,sizeof dp); inf=dp[0][0][0]; cin>>T; while(T--){ cin>>n>>m; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ scanf("%d",&grid[i][j]); } } dp[0][0][grid[0][0]]=sq(grid[0][0]); pos[0][0][0]=grid[0][0]; h[0][0]=1; int ans=inf; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ for(int k=0;k<h[i][j];k++){ int v=pos[i][j][k]; if(dp[i+1][j][v+grid[i+1][j]]==inf){ pos[i+1][j][h[i+1][j]++]=v+grid[i+1][j]; dp[i+1][j][v+grid[i+1][j]]=dp[i][j][v]+sq(grid[i+1][j]); }else{ dp[i+1][j][v+grid[i+1][j]]= min(dp[i][j][v]+sq(grid[i+1][j]), dp[i+1][j][v+grid[i+1][j]]); } if(dp[i][j+1][v+grid[i][j+1]]==inf){ pos[i][j+1][h[i][j+1]++]=v+grid[i][j+1]; dp[i][j+1][v+grid[i][j+1]]=dp[i][j][v]+sq(grid[i][j+1]); }else{ dp[i][j+1][v+grid[i][j+1]]= min(dp[i][j][v]+sq(grid[i][j+1]), dp[i][j+1][v+grid[i][j+1]]); } if(i==n-1&&j==m-1){ ans=min(ans,dp[i][j][v]*(n+m-1)-v*v); } dp[i][j][v]=inf; } h[i][j]=0; } } for(int i=0;i<=max(n,m);i++){ for(int j=0;j<h[i][m];j++){ int v=pos[i][m][j]; dp[i][m][v]=inf; } h[i][m]=0; for(int j=0;j<h[n][i];j++){ int v=pos[n][i][j]; dp[n][i][v]=inf; } h[n][i]=0; } printf("Case #%d: %d\n",++cas,ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/Cw-trip/p/4843869.html