poj3186

来源:互联网 发布:塞班软件下载网站 编辑:程序博客网 时间:2024/05/29 16:00

题目传送门
简单区间dp;
本人代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn=2000+5;int d[maxn][maxn],a[maxn];int dp(int i,int j,int k);int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)    scanf("%d",&a[i]);    memset(d,0,sizeof(d));    int ans=dp(1,n,1);    printf("%d\n",ans);}int dp(int i,int j,int k){    if(d[i][j]>0) return d[i][j];    int& ans=d[i][j];    if(i==j) return ans=a[i]*k;    else return ans=max(dp(i+1,j,k+1)+a[i]*k,dp(i,j-1,k+1)+a[j]*k);}

看了邝斌大大的代码感觉加深了对区间dp的理解:
此处的dp[i][j]表示的是第(n-(j-i))+1次(可直接计算出来)取范围在i-j的最大值。

/*POJ  3186*/#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>using namespace std;const int MAXN=2020;int a[MAXN];int dp[MAXN][MAXN];int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        for(int i=1;i<=n;i++)          scanf("%d",&a[i]);        memset(dp,0,sizeof(dp));        for(int i=1;i<=n;i++)  //初始化,表示在最后一次取a[i]          dp[i][i]=a[i]*n;        for(int k=1;k<n;k++)  //**此处直接用k记录第几次取**          for(int i=1;i+k<=n;i++)          {              int j=i+k;              dp[i][j]=max(dp[i+1][j]+(n-k)*a[i],dp[i][j-1]+(n-k)*a[j]);          }        printf("%d\n",dp[1][n]);    }    return 0;}
0 0