Problem:http://pan.baidu.com/s/1dDD5Xsd
solution : 轮廓线DP
#include<map>
#include<queue>
#include<stack>
#include<utility>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<iostream>
#include<algorithm>
#define Mp(x,y) std::make_pair(x,y)
const int MAXN = 55, MAXM = 505 , INF = 2e8;
const long long LINF = 1e14;
int n , m, t[MAXN][MAXN];
long long sum[MAXN][MAXN];
long long f[MAXN][MAXN][MAXM];
long long ans = 0;
int main()
{
#ifndef ONLINE_JUDGE
freopen("skill.in","r",stdin);
freopen("skill.out","w",stdout);
#endif
std::cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n - i + 1 ; j++)
{
scanf("%d",&t[i][j]);
sum[i][j] = sum[i-1][j] + t[i][j];
}
memset(f,-1,sizeof(f));
f[0][1][0] = 0;
for(int j = 1; j <= n + 1; j++)
{
for(int i = 0,k = 0; k <= m; k++)
{
f[i][j][k] = std::max(f[i][j][k],f[i][j-1][k]);
f[i][j][k] = std::max(f[i][j][k],f[i+1][j-1][k]);
}
for(int i = 1; i <= n + 1 - j; i++)
for(int k = 0; k <= m; k++)
{
if(k-1 >= 0 && f[i-1][j][k-1] != -1)
f[i][j][k] = t[i][j] + f[i-1][j][k-1];
if(k-i >= 0 && f[i+1][j-1][k-i] != -1)
{
long long tmp = f[i+1][j-1][k-i] + sum[i][j];
f[i][j][k] = std::max(f[i][j][k],tmp);
}
}
}
for(int i = 0,j = 1; j <= n + 1; j++)
for(int k = 0; k <= m; k++)
ans = std::max(ans,f[i][j][k]);
std::cout << ans << std::endl;
fprintf(stderr,"%f",clock()*1.0/CLOCKS_PER_SEC);
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}