HDU 3507(斜率优化dp

题目:每次选取连续的若干数字的代价

要求选取虽有数字的最小代价.

思路:基础斜率dp题,题解见http://www.cnblogs.com/kuangbin/archive/2012/08/26/2657650.html

/*
* @author:  Cwind
*/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (1e-6)
#define IINF (1<<29)
#define LINF (1ll<<59)
#define INF (1000000000)
#define FINF (1e3)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> P;

const int maxn=5e5+3000;
int n,m;
int a[maxn];
int Q[maxn];
int sum[maxn];
int dp[maxn];
int front,back;
int get1(int a,int b){
    return dp[b]+sq(sum[b])-dp[a]-sq(sum[a]);
}
int get2(int a,int b){
    return 2*(sum[b]-sum[a]);
}
int main(){
    freopen("/home/files/CppFiles/in","r",stdin);
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
    while(cin>>n>>m){
        front=back=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        Q[back++]=0;
        for(int i=1;i<=n;i++){
            while(front+1<back&&get1(Q[front],Q[front+1])<=sum[i]*get2(Q[front],Q[front+1])){
                 front++;
            }
            dp[i]=dp[Q[front]]+sq(sum[i]-sum[Q[front]])+m;
            while(front+1<back&&get1(Q[back-2],Q[back-1])*get2(Q[back-1],i)>=get1(Q[back-1],i)*get2(Q[back-2],Q[back-1])){
                back--;
            }
            Q[back++]=i;
        }
        printf("%d\n",dp[n]);
    }
    return 0;
}

时间: 2024-12-19 12:37:30

HDU 3507(斜率优化dp的相关文章

HDU 3507斜率优化dp

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 12185    Accepted Submission(s): 3733 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu

hdu 3507 斜率优化

我的第一道斜率优化. 就这道题而言,写出原始的方程: dp[i] = min{ dp[j] + (sum[i]-sum[j])2  + M | j in [0,i) } O(n^2)的复杂度肯定超时,要么优化转移,要么重写方程. 斜率优化的思想就是减少不必要的枚举(即不枚举肯定不会成为决策点的j). 我们考虑两个位置p<q<i “选择q比选择p优” 当且仅当 dp[q]+(sum[i]-sum[q])2+M < dp[p]+(sum[i]-sum[p])2+M 化简右边即: [ (dp[

hdu 3669(斜率优化DP)

Cross the Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327680/327680 K (Java/Others)Total Submission(s): 4479    Accepted Submission(s): 812 Problem Description “Across the Great Wall, we can reach every corner in the world!” Now the

Fxx and game hdu 5945 斜率优化dp

dfs你怕是要爆炸 考虑dp; 很容易想到 dp[ i ] 表示到 i 时的最少转移步数: 那么: dp[ i ]= min( dp[ i ],dp[ i-j ]+1 ); 其中 i-t<=j<=i; 当 i%k==0时 ,dp[ i ]=min( dp[ i ],dp[ i/k ]+1 ): 很明显这种要T到飞起: 我们要优化dp: 1e6的数据考虑O(n)级别的: 斜率优化: #include<iostream> #include<cstdio> #include&

HDU 4258 斜率优化dp

Covered Walkway Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1496    Accepted Submission(s): 602 Problem Description Your university wants to build a new walkway, and they want at least p

Print Article hdu 3507 一道斜率优化DP 表示是基础题,但对我来说很难

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 4990    Accepted Submission(s): 1509 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antique

HDU 3507 Print Article(斜率优化DP)

题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上的资料,看得还挺懂的,不过我觉得如果以后真遇到斜率DP,要推起来肯定不简单..... 网上资料1 网上资料2 1 #include <iostream> 2 #include <stdio.h> 3 4 using namespace std; 5 6 int q[500005],dp

hdu 3507 斜率dp

不好理解,先多做几个再看 此题是很基础的斜率DP的入门题. 题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 设dp[i]表示输出前i个的最小费用,那么有如下的DP方程: dp[i]= min{ dp[j]+(sum[i]-sum[j])^2 +M }  0<j<i 其中 sum[i]表示数字的前i项和. 相信都能理解上面的方程. 直接求解上面的方程的话复杂度是O(n^2) 对于500000的规模显然是超时的.下面讲解下如何用斜率

hdu 2993 MAX Average Problem (斜率优化dp入门)

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5855    Accepted Submission(s): 1456 Problem Description Consider a simple sequence which only contains positive integers as