组队赛130926 Regionals 2011, Latin America

B题:从一个三角形中选一些点,求和的最大值,不过如果选某个点,必须先取了这个点上面的两个点。

dp[i][j]表示沿着斜角方向取,包含某个点的最大值。

dp[i][j]=max(max(dp[k][j]),dp[i-1][j-1]+b[i][j]);b[i][j]表示j列从1-i行的和。

这题主要是想到dp[i][j],枚举所有的情况都可以用dp[i][j]来表示。

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 1005
#define INF 0xfffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define FOR(i,s,t) for(int i=s;i<=t;i++)
#define ull unsigned long long
#define ll long long
using namespace std;
int a[maxn][maxn],b[maxn][maxn];//b[]表示从上到小该列的和
int dp[maxn][maxn];//表示以取改点且以改点为最低点的和的最大值
int main()
{
    int n;
    while(scanf("%d",&n)&&n!=0)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=i;j++)
            {
                scanf("%d",&a[i][j]);
                b[i][j]=b[i-1][j]+a[i][j];
            }
        }
        memset(dp,0,sizeof(dp));
        int ans=0;
        for(int j=1;j<=n;j++)//从每一列开始
        {
            for(int i=n;i>=j;i--)
            {
                if(i==n)
                {
                    dp[i][j]=dp[i-1][j-1]+b[i][j];
                }
                else
                dp[i][j]=max(dp[i-1][j-1]+b[i][j],dp[i+1][j]);
                ans=max(ans,dp[i][j]);
            }
            cout<<endl;
        }
        printf("%d\n",ans);
    }
	return 0;
}


你可能感兴趣的:(组队赛130926 Regionals 2011, Latin America)