码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3017

时间:2015-05-13 22:01:01      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:dp   优化   

长度为 n 的数列,要求把这个数列划分为任意块,每块的元素和小于 m,使得所有块的最大值的和最小。


思路:

很明显的一个转移方程是: dp[i] = max(dp[j] + max(a[j+1], a[j+2], ..., a[i])); 其中满足 sum[i] - sum[j] <= M 的 j 都算,这是一个 O(N * N) 的解法,肯定超时。,那么就要用优化的方法 ,对着题解看了一个小时终于看懂了。


f[j]表示前j个数分为若干份,最优解。
g[i]表示使f[i]取得最优解的j,即最后一份为从g[i]分到i。
把第i+1个数加入进来。
如果超过了m,则把前面的数减去,直至小于m。
当总数小于m时:
如果a[i+1]小于mx(g[i]到i中的最大值)则可以忽略,f[i]=f[i-1],g[i]=g[i-1];
如果a[i+1]大于mx,则要确定最优值。(优化)因为f[i+1]的最优值不会再(g[i-1],i)内,所以可以直接从p到i+1计算。p为第p个数使p到i+1的总和小于m。但如果g[i-1]小于p,就要从i计算到p。

(g[i-1]>=p?g[i-1]:i);意思是如果之前的最大值不在当前字块内,那么就从i->p计算最大值之和的最小值;如果最大值还在的话,那么就只需要在计算g【i-1】== p处的最大值之和的最小值。其实就是更新一下f【i】和g【i】;如果f[i]>f[j-1]+mx的话,那么最优解肯定不是以g[i]为下标的那个解。那么更新f【i】=j;如果是f[i]<f[j-1]+mx,那么就不更新g[i]。


#include<iostream>
#include <cstdio>
using namespace std;
#define maxn 101010
typedef long long ll;
const ll inf=1000000000;
ll f[maxn];
int g[maxn];
ll a[maxn];
int n;
ll m;
int main()
{
    int i,j;
    while(scanf("%d%I64d",&n,&m)!=-1)
    {
        for(i=1; i<=n; i++)
        {
            scanf("%I64d",&a[i]);
            if(a[i]>m)
            {
                printf("-1\n");
                return 0;
            }
        }
        f[1]=a[1];
        g[1]=1;
        int p=1;
        f[0]=0;//因为当第一次更新的时候那个需要计算f[0]+mx,所以我们应该给f【0】赋值
        ll mx=a[1],sum=a[1];

        for(i=2; i<=n; i++)
        {
            int k=0;
            f[i]=inf;
            sum+=a[i];
            while(sum>m)sum-=a[p++];
            if(mx>=a[i]&&g[i-1]>=p)
            {
                f[i]=f[i-1];
                g[i]=g[i-1];
            }
            else
            {
                mx=a[i];
                 k=(g[i-1]>=p?g[i-1]:i);

                for(j=k; j>=p; j--)
                {
                    mx=max(mx,a[j]);
                    g[i]=f[i]>mx+f[j-1]?j:g[i];
                    f[i]=min(f[i],f[j-1]+mx);
                }
                mx=f[i]-f[g[i]-1];
            }

        }
        printf("%I64d\n",f[n]);
    }
}









poj 3017

标签:dp   优化   

原文地址:http://blog.csdn.net/u013076044/article/details/45697415

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!