Gym 100829S_surf 动态规划的优化

题目大意是,非你若干个任务,任务分别对应开始时间、预期收益、持续时间三项指标,让你从中选择一个受益最大的方案(没有开始时间相同的任务)。

于是,标准状态转移方程应当为,设DP[K]为选择了前K个任务的最大收益,后面转移为DP[K+1]=MAX且能够共存的(DP[I]);很容易想到N^2的暴力更新,但是这题数量太大,会炸得连渣都不剩。于是需要优化到较低的数量级(比如NLOGN)

注意到,我们也许不用对某个任务来选取前K个的最大值,不容易想到优化但是想想刘汝佳同志的话——不方便直接求解的时候想想更新状态看看,于是就变成了状态更新公式而不是状态转移方程。——对于求得的DP[K]更新所有合法 的,大于K的DP值。注意到,当前序列已经经过了排序,所以,当找到第一个合法的DP[P]P>K时候,就会有P+1也是合法的状态,因此很容易想到树状数组相对最大值+二分查找确定位置(只要有比较函数就可以写二分)。最后复杂度是NLOGN。

另外根据某些奇怪的树上的书法,,任何一个动态规划的优化算法都应当从如下三个状态进行考虑:
1、状态总数        N    N

2、决策数         N    1

3、状态转移时间复杂度   1    LOGN

分别对应原始DP和优化后的DP

AC代码如下:考虑到没有校园网所以在VJ上面交的。。。于是投篮用了万能头文件,好孩子不要学我哟~

#include<bits/stdc++.h>
using namespace std;

const long long MAXN=300233;

class Mession
{
    public:
        long long a,b,p;
};Mession messions[MAXN];
long long tree[MAXN];
long long dp[MAXN];
long long n;
void insert(int pos,long long key)
{
    while(pos<=n)
    {
        tree[pos]=max(key,tree[pos]);
        pos+=pos&(-pos);
    }
}
long long getSum(int pos)
{
    long long ans=0;
    while(pos)
    {
        ans=max(tree[pos],ans);
        pos-=pos&(-pos);
    }return ans;
}
bool cmp(Mession m1,Mession m2)
{
    return m1.a<m2.a;
}
void init()
{
cin>>n;
    for(int i=1;i<=n;++i)
    {
        cin>>messions[i].a>>messions[i].p>>messions[i].b;
        messions[i].b+=messions[i].a;
    }sort(messions+1,messions+n+1,cmp);
    long long ans=0;
    for(int i=1;i<=n;++i)
    {
        dp[i]=messions[i].p;
        dp[i]+=getSum(i);
        Mession mm;mm.a=messions[i].b;
        int pos=lower_bound(messions+1,messions+1+n,mm,cmp)-messions;
        insert(pos,dp[i]);
        ans=max(dp[i],ans);
    }
    cout<<ans<<endl;
}

int main()
{
    cin.sync_with_stdio(false);
    init();
    return 0;
}
时间: 2024-10-23 22:08:51

Gym 100829S_surf 动态规划的优化的相关文章

$Dynamic Planning Optimization$ 关于动态规划的优化方案(%$\color{red}{rqy}$)

关于动态规划的优化方案(%\(\color{red}{rqy}\)) 1.单调队列 单调队列是一种具有单调性的队列,其中的元素全部按照递增或者递减的顺序排列,就比如下面这个递减队列. 假如说我们要在队尾加入一个\(5\),那么我们入队的步骤就是这样的: 发现队尾\(1\),(q[tail]),\(1<5\),则将1退出(tail--) 发现队尾\(2\),(q[tail]),\(2<5\),则将2退出(tail--) 发现队尾\(3\),(q[tail]),\(3<5\),则将3退出(t

动态规划(斜率优化):BZOJ 1010 【HNOI2008】 玩具装箱

玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8218  Solved: 3233[Submit] Description P 教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维 容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的. 同时如果一个一维

Evensgn的OI学习笔记(一)——动态规划及其优化

Author : Evensgn Date : 2014-12-08 蒟蒻也要写笔记啦~ (1)矩阵乘法优化DP 矩阵乘法: 一个 a*b 的矩阵 M1 与一个 b*c 的矩阵 M2 相乘,得到一个 a*c 的矩阵 M3. M3[i][j] = sigma(M1[i][k] * M2[k][j])      ( i <= a; j <= c; k <= b ) M3 的一个元素 M3[i][j] 是矩阵 M1 的第 i 行与 M2 的第 j 列的每一个对应元素乘积的和. 注意:矩阵 M1

动态规划(斜率优化):BZOJ 3675 [Apio2014]序列分割

Description 小H最近迷上了一个分割序列的游戏.在这个游戏里,小H需要将一个长 度为N的非负整数序列分割成k+l个非空的子序列.为了得到k+l个子序列, 小H将重复进行七次以下的步骤: 1.小H首先选择一个长度超过1的序列(一开始小H只有一个长度为n的 序列一一也就是一开始得到的整个序列): 2.选择一个位置,并通过这个位置将这个序列分割成连续的两个非空的新 序列. 每次进行上述步骤之后,小H将会得到一定的分数.这个分数为两个新序 列中元素和的乘积.小H希望选择一种最佳的分割方案,使得

BZOJ1911 [Apio2010]特别行动队 - 动态规划 - 斜率优化

欢迎访问~原文出处--博客园-zhouzhendong&AK 去博客园看该题解 题目传送门 题意概括 把一个整数序列划分成任意连续的段,使得划分出来的每一段的价值和最大. 对于某一段,价值的计算公式为 V=ax^2+bx+c,其中 x 为当前段的数值和. 题解 这题是博主大蒟蒻的第一道斜率优化DP题-- C++:while (1) 懵逼++; Pascal:while (true) do inc(懵逼); 本题首先一看就是 DP 题. 但是一看 1<=n<=1000000,-5<

BZOJ3156 防御准备 动态规划 斜率优化

原文链接http://www.cnblogs.com/zhouzhendong/p/8688187.html 题目传送门 - BZOJ3156 题意 长为$n$的序列$A$划分,设某一段为$[i,j]$,则其花费为$A_j+\sum_{k=i}^{j}(j-k)$. 一种划分方式的花费就是他每一段的花费和. 最小化花费. $n\leq 10^6$ 题解 斜率优化裸题. 设$dp_i$表示序列前$i$项通过划分可以到的最小花费. 则 $$dp_i=min\{dp_j+a_i+\frac{(i-j)

Codeforces Gym 101623A - 动态规划

题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分. 我们将这个序列排序,对于权值相同的一段数可以任意交换它们,每两个相邻数在原序列的位置中如果是$i, i + 1$,那么划分的段数就可以减少1. 每次转移我们考虑添加值相同的一段. 每次转移能不能将减少的段数加一取决于当前考虑的数在前一段内有没有出现以及有没有作为最左端点. 因此我们记录一个决策与

动态规划(斜率优化):SPOJ Commando

Commando You are the commander of a troop of n soldiers, numbered from 1 to n. For the battle ahead, you plan to divide these n soldiers into several com-mando units. To promote unity and boost morale, each unit will consist of a contiguous sequence

CCF(压缩编码):动态规划+平行四边形优化

压缩编码 201612-4 一开始看这题还以为是哈夫曼编码的题目,结果是哈夫曼题目的变形. 哈夫曼编码是每次合并任意两堆石子,而这里的题目是合并相邻的两堆石子,而且这里的合并花费是合并两堆石子加上所有的叶子结点. 参考图解:https://blog.csdn.net/more_ugly_less_bug/article/details/60142954 石子问题:https://blog.csdn.net/acdreamers/article/details/18039073 #include<