这是我的第一份文章,希望自己能坚持下去!!!
题目思路:一开始想的是用二维数组DP做,但是想了一下还是决定试试一维数组,正好每层的个数与层数是相等的,是一个等差数列,所以可以用一维数组表示。我的一维做法是从上往下推的,需要注意每层要独立判断左右两端,其他的基本就和 二维差不多了,但是二维数组还是要简便许多。
先附上一维数组DP的做法
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxa 1000000
#define inf -1
int dp[maxa];
int a[maxa];
int getSum(int x) {
return (1+x)*x/2;
}
int main() {
int C,i,j;
scanf("%d",&C);
while(C>0) {
int N,maxv,sum,front,back,level;
maxv=inf;
front=2;
back=3;
level=2;
scanf("%d",&N);
sum=getSum(N);
for(i=1; i<=sum; i++) {
scanf("%d",&a[i]);
}
dp[1]=a[1];
maxv=max(maxv,dp[1]);
for(i=2; i<=sum; i++) {
if(i!=front && i!=back) {
dp[i]=max(dp[i-level],dp[i-level+1])+a[i];
} else if(i==front) {
dp[i]=dp[i-level+1]+a[i];
front+=level;
} else {
dp[i]=dp[i-level]+a[i];
level++;
back+=level;
}
maxv=max(maxv,dp[i]);
}
printf("%d\n",maxv);
C--;
}
return 0;
}
再附上二维数组的做法,二维数组与一维相反,是从下往上推的,因为最终的输出答案必定是dp[1][1],这样也可以减少设置过多的变量。
#include <iostream>
#include <cstdio>
using namespace std;
#define maxa 200
int dp[maxa][maxa];
int main() {
int i,j,C,n;
scanf("%d",&C);
while(C) {
scanf("%d",&n);
for(i=1;i<=n;i++) {
for(j=1;j<=i;j++) {
scanf("%d",&dp[i][j]);
}
}
for(i=n-1;i>=1;i--) {
for(j=1;j<=i;j++) {
dp[i][j]+=max(dp[i+1][j],dp[i+1][j+1]);
}
}
printf("%d\n",dp[1][1]);
C--;
}
return 0;
}
码风可能有点丑?,大家见谅。