zoukankan      html  css  js  c++  java
  • UESTC 876 爱管闲事 --DP

    题意:即求给定n个数字(a1,a2,……an),不改变序列,分成M份,使每一份和的乘积最大。

    思路:dp[i][j]表示把前i个数字,分成j份所能得到的最大乘积。

    转移方程:dp[i][j] = max{ dp[k][i-1]*sum(k+1,j) }  其中显然j<=i(分成j份,至少要有i个数才能分)且i-1<=k<j

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 10007
    
    int a[22],dp[22][22],sum[22];
    
    int SUM(int l,int r)
    {
        return sum[r]-sum[l-1];
    }
    
    int main()
    {
        int t,i,n,m,j,k;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            sum[0] = 0;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                sum[i] = sum[i-1] + a[i];
            }
            for(i=0;i<=21;i++)
            {
                for(j=0;j<=i;j++)
                    dp[i][j] = 1;
                for(j=i+1;j<=21;j++)
                    dp[i][j] = 0;
            }
            for(i=1;i<=n;i++)
            {
                int s = 1;
                for(j=1;j<=i;j++)
                    s *= a[j];
                dp[i][i] = s;
            }
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=i;j++)
                {
                    int maxi = -1;
                    for(k=j-1;k<i;k++)
                    {
                        maxi = max(maxi,dp[k][j-1]*SUM(k+1,i));
                    }
                    dp[i][j] = max(maxi,dp[i][j]);
                }
            }
            printf("%d
    ",dp[n][m]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    map
    01背包和完全背包 POJ
    并查集 计算节点数量
    set
    map,vector,queue 图 综合运用
    并查集 hdu-1325 Is It A Tree?
    js中的ajax
    java算法
    MySql在Window上的安装
    微信开发账号要求
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3762733.html
Copyright © 2011-2022 走看看