Greedy Pie Eaters(区间DP板子)

Posted sylvia1111

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Greedy Pie Eaters(区间DP板子)相关的知识,希望对你有一定的参考价值。

题目描述

Farmer John has M cows, conveniently labeled 1…M, who enjoy the occasional change of pace from eating grass. As a treat for the cows, Farmer John has baked N pies (1≤N≤300), labeled 1…N. Cow i enjoys pies with labels in the range [li,ri] (from li to ri inclusive), and no two cows enjoy the exact same range of pies. Cow i also has a weight, wi, which is an integer in the range 1…106.
Farmer John may choose a sequence of cows c1,c2,…,cK, after which the selected cows will take turns eating in that order. Unfortunately, the cows don‘t know how to share! When it is cow ci‘s turn to eat, she will consume all of the pies that she enjoys --- that is, all remaining pies in the interval [lci,rci]. Farmer John would like to avoid the awkward situation occurring when it is a cows turn to eat but all of the pies she enjoys have already been consumed. Therefore, he wants you to compute the largest possible total weight (wc1+wc2+…+wcK) of a sequence c1,c2,…,cK for which each cow in the sequence eats at least one pie.

SCORING:
Test cases 2-5 satisfy N≤50 and M≤20.
Test cases 6-9 satisfy N≤50.

输入

The first line contains two integers N and M (1≤M≤N(N+1)/2).
The next M lines each describe a cow in terms of the integers wi,li, and ri.

输出

Print the maximum possible total weight of a valid sequence.

样例输入 Copy

2 2
100 1 2
100 1 1

样例输出 Copy

200

提示

In this example, if cow 1 eats first, then there will be nothing left for cow 2 to eat. However, if cow 2 eats first, then cow 1 will be satisfied by eating the second pie only.

区间dp的基础知识
定义 :区间dp就是在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的 最优解进而得出整个大区间上最优解的dp算法。
最基础的伪代码
 1 //mst(dp,0) 初始化DP数组
 2 for(int i=1;i<=n;i++)
 3 {
 4     dp[i][i]=初始值
 5 }
 6 for(int len=2;len<=n;len++)  //区间长度
 7 for(int i=1;i<=n;i++)        //枚举起点
 8 {
 9     int j=i+len-1;           //区间终点
10     if(j>n) break;           //越界结束
11     for(int k=i;k<j;k++)     //枚举分割点,构造状态转移方程
12     {
13         dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+w[i][j]);
14     }
15 }
16 
17 原文链接:https://blog.csdn.net/my_sunshine26/article/details/77141398
平行四边形优化
用s[i][j]表示区间[i,j]中的最优分割点,那么第三重循环可以从[i,j-1)优化到【s[i][j-1],s[i+1][j]】。(这个时候小区间s[i][j-1]和s[i+1][j]的值已经求出来了,然后通过这个循环又可以得到s[i][j]的值)
技术图片
 1 mst(dp,0x3f);
 2         for(int i=1;i<=n;i++)
 3         {
 4             scanf("%d",&x);
 5             sum[i]=sum[i-1]+x;
 6             dp[i][i]=0;
 7             s[i][i]=i;
 8         }
 9         for(int len=2;len<=n;len++)
10         for(int i=1;i<=n;i++)
11         {
12             int j=i+len-1;
13             if(j>n) continue;
14             for(int k=s[i][j-1];k<=s[i+1][j];k++)
15             {
16                 if(dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]<dp[i][j])
17                 {
18                     dp[i][j]=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];
19                     s[i][j]=k;
20                 }
21             }
22         }
23         printf("%d
",dp[1][n]);
View Code

 

本题AC代码

#include<bits/stdc++.h>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
const int N=310;
int dp[N][N],w[N][N][N],f[N][N];
int n,m;
 
void DP()
{
        for(int i=1;i<=n;i++){
        for(int j=i;j>=1;j--){
            //for(int k=i,k<=j-1;k++)f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]);
            for(int k=i;k<=n;k++){
                if(j>1)
                    w[i][j-1][k]=max(w[i][j-1][k],w[i][j][k]);
                if(k<n)
                   w[i][j][k+1]=max(w[i][j][k+1],w[i][j][k]);
            }
        }
    }
      for(int i=n;i>=1;i--){
        for(int j=i;j<=n;j++){
            for(int k=i;k<=j-1;k++)dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
            for(int k=i;k<=j;k++) dp[i][j]=max(dp[i][j],w[k][i][j]+(k>i?dp[i][k-1]:0)+(k<j?dp[k+1][j]:0));
        }
    }
 
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int ww,l,r;
        scanf("%d%d%d",&ww,&l,&r);
        for(int j=l;j<=r;j++)
            w[j][l][r]=max(ww,w[j][l][r]);
    }
    DP();
    printf("%d
",dp[1][n]);
    return 0;
}

 

以上是关于Greedy Pie Eaters(区间DP板子)的主要内容,如果未能解决你的问题,请参考以下文章

题目1453:Greedy Tino(dp题目)

[您有新的未分配科技点]数位dp:从懵X到板子

Greedy Sequence(主席树-区间小于每个数的最大值)

Codeforces1312E Array Shrinking 区间DP

HDU P2089

Luogu-P2758 编辑距离