POJ3616-Milking Time-(dp)

题意:牛有m个时间段可以挤奶,每个时间段的开始时间,结束时间,挤奶量不尽相同,寄完一次需要休息r时间,求在n时间内如何安排牛挤奶产量最大。

解题:

1.休息r时间,当做结束时间需要+r

2.以结束时间的先后对各个时间段排序,然后dp求最值。dp[i]表示当前到了第i个时间段。

3.状态转移方程:dp[i] = max( dp[i],dp[j]+a[i].v );

4.条件:当前i时间段的挤奶任务的开始时间 >= 以前j时间段的结束时间

简而言之,对m个时间段遍历,每次都求当前时间段 及以前的时间段 一起 挤奶量最大化。当前的dp[i]产量 与 以前时间段的最大挤奶量续上本次时间段的产量。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
#define p 1000000007
using namespace std;

int n,m,r;
struct node
{
    int l;
    int r;
    int v;
};
node a[10086];
int dp[10086];

bool cmp( node p1,node p2 )
{
    return p1.r<p2.r;
}


int main()
{
    while( scanf("%d %d %d",&n,&m,&r)!=EOF )
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=m;i++)
            scanf("%d %d %d",&a[i].l,&a[i].r,&a[i].v),a[i].r+=r;
        sort(a+1,a+m+1,cmp);
        /*
        printf("
");
        for(int i=1;i<=m;i++)
        printf("%d %d %d 
",a[i].l,a[i].r,a[i].v);
        */
        int maxx=-inf;
        for(int i=1;i<=m;i++)///当前的时间段
        {
            dp[i]=a[i].v;///先赋值 第i个时间段自己的产量
            //printf("dp[%d]=%d
",i,dp[i]);观察dp变化
            for(int j=i-1;j>=1;j--)///接前面的时间段
            {
                if( a[i].l >= a[j].r )
                    dp[i] = max( dp[i],dp[j]+a[i].v );
                
            }
            //printf("dp[%d]=%d
",i,dp[i]);
            maxx=max(maxx,dp[i]);
        }
        printf("%d
",maxx);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shoulinniao/p/11206229.html