zoukankan      html  css  js  c++  java
  • 区间DP Treats for the Cows POJ

    题意:给长度为n的序列,每次只能从首或尾取一个数,第i次取的数权值为(数值*i),求取完所有的数可以达到的最大权值。

    网上都说是简单dp,自己想了很久都没想明白。。。

    从后面推前面,由小区间推大区间。dp[i][j]代表要取的区间[i,j] ,区间长度为n的序列,从区间长度为1开始推,dp[i][i]=n*a[i]表示最后一个取走的数是i;

    当区间长度为2时 dp[i][i+1]=max(dp[i][i]+a[i+1]*(n-1),dp[i+1][i+1]+a[i]*(n-1)) 表示从(最后取走的数是i,倒数第二取走的数是i+1),(最后取走的数是i+1,倒数第二取走的数是 i)中取最大值。

    dp[i][j]=max(dp[i+1][j]+a[i]*(n-j+i),dp[i][j-1]+a[j]*(n-j+i));

    想清楚后还是蛮简单的。。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define maxn 2005
    using namespace std;
    int a[maxn],dp[maxn][maxn];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            dp[i][i]=n*a[i];
        }
        for(int l=2;l<=n;l++)
        {
            for(int i=1;i<=n-l+1;i++)
            {
                int j=i+l-1;
                dp[i][j]=max(dp[i+1][j]+a[i]*(n-l+1),dp[i][j-1]+a[j]*(n-l+1));
            }
        }
        printf("%d
    ",dp[1][n]);
        return 0;
    }
    View Code
  • 相关阅读:
    用内联取代宏代码
    参数的缺省值
    令人迷惑的隐藏规则
    重载与覆盖
    重载是如何实现的?
    重载的起源
    C++函数的高级特性
    使用调试器逐步跟踪程序
    new/delete 的使用要点
    malloc/free 的使用要点
  • 原文地址:https://www.cnblogs.com/Twsc/p/7354340.html
Copyright © 2011-2022 走看看