hdu4719 Oh My Holy FFF[线段树优化dp]

Oh My Holy FFF

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 1047    Accepted Submission(s): 291

Problem Description

N soldiers from the famous "*FFF* army" is standing in a line, from left to right.

 o   o   o   o   o   o   o   o   o   o   o   o   o   o   o   o   o   o/F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\/ \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \

You, as the captain of *FFF*, want to divide them into smaller groups, but each group should still be continous in the original line. Like this:

 o   o   o  |  o   o   o   o  |  o   o   o   o   o   o  |  o   o   o   o   o/F\ /F\ /F\ | /F\ /F\ /F\ /F\ | /F\ /F\ /F\ /F\ /F\ /F\ | /F\ /F\ /F\ /F\ /F\/ \ / \ / \ | / \ / \ / \ / \ | / \ / \ / \ / \ / \ / \ | / \ / \ / \ / \ / \

In your opinion, the number of soldiers in each group should be no more than L.
Meanwhile, you want your division be "holy". Since the soldier may have different heights, you decide that for each group except the first one, its last soldier(which is the rightmost one) should be strictly taller than the previous group‘s last soldier. That is, if we set bi as the height of the last soldier in group i. Then for i >= 2, there should be bi > bi-1.
You give your division a score, which is calculated as , b0 = 0 and 1 <= k <= M, if there are M groups in total. Note that M can equal to 1.
Given the heights of all soldiers, please tell us the best score you can get, or declare the division as impossible.

Input

The first line has a number T (T <= 10) , indicating the number of test cases.
For each test case, first line has two numbers N and L (1 <= L <= N <= 105), as described above.
Then comes a single line with N numbers, from H1 to Hn, they are the height of each soldier in the line, from left to right. (1 <= Hi <= 105)

Output

For test case X, output "Case #X: " first, then output the best score.

Sample Input

2
5 2
1 4 3 2 5
5 2
5 4 3 2 1

Sample Output

Case #1: 31
Case #2: No solution

Source

2013 ACM/ICPC Asia Regional Online —— Warmup2

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define lc k<<1
#define rc k<<1|1
using namespace std;
typedef long long ll;
const int N=1e5+5;
struct node{ll a,p;}d[N];
int n,T,L,cas;ll f[N];ll mx[N<<2];
void change(int k,int l,int r,int p,ll v){
    if(l==r){mx[k]=v;return ;}
    int mid=l+r>>1;
    if(p<=mid) change(lc,l,mid,p,v);
    else change(rc,mid+1,r,p,v);
    mx[k]=max(mx[lc],mx[rc]);
}
ll query(int k,int l,int r,int x,int y){
    if(l==x&&r==y) return mx[k];
    int mid=l+r>>1;
    if(y<=mid) return query(lc,l,mid,x,y);
    else if(x>mid) return query(rc,mid+1,r,x,y);
    else return  max(query(lc,l,mid,x,mid),query(rc,mid+1,r,mid+1,y));
}
bool operator <(const node &x,const node &y){
    return x.a!=y.a?x.a<y.a:x.p>y.p;
}
void work(){
    ll nv,pre;
    scanf("%d%d",&n,&L);
    for(int i=1;i<=n;i++) scanf("%I64d",&nv),d[i].a=nv,d[i].p=i;
    sort(d+1,d+n+1);
    memset(f,-1,sizeof f);
    fill(mx,mx+(n<<2),-1);
    change(1,0,n,0,0);
    for(int i=1,ni;i<=n;i++){
        ni=d[i].p;
        nv=d[i].a;
        pre=query(1,0,n,max(0,ni-L),ni-1);
        if(pre>=0){
            f[ni]=pre+nv*nv;
            change(1,0,n,ni,f[ni]-nv);
        }
        if(ni==n) break;
    }
    if(f[n]>0) printf("%I64d\n",f[n]);
    else puts("No solution");
}
int main(){
    for(scanf("%d",&T);T--;){
        printf("Case #%d: ",++cas);work();
        /*for(int i=1;i<=n;i++) scanf("%d",a+i);
        for(int i=1;i<=n;i++){
            for(int j=max(0,i-L);j<i;j++){
                if(a[i]>a[j]){
                    f[i]=max(f[i],f[j]+a[i]*a[i]-a[j]);
                }
            }
        }
        if(!f[n]) puts("No solution");
        else printf("%d\n",f[n]);*/
    }
    return 0;
}
时间: 2024-08-05 19:01:16

hdu4719 Oh My Holy FFF[线段树优化dp]的相关文章

BZOJ 1835 基站选址(线段树优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1835 题意:有N个村庄坐落在一条直线上,第 i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci.如果在距离第i个村 庄不超过Si的范围内建立了一个通讯基站,那么就成它被覆盖了.如果第i个村庄没有被覆盖,则需要向他们补偿,费用为Wi.现在的问题是,选择基站的位 置,使得总费用最小. 思路: 另外,程序中的n=n+1,m=

【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp

题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John's cows have invented a variant of the game for themselves to play. Being played by clumsy animals weighing nearly a ton, Cow Hopscotch almost always ends in disaster, but this has

[Poi2010]Monotonicity 2 (线段树优化DP)

题目描述 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k].选出一个长度为L的子序列(不要求连续),要求这个子序列的第i项和第i+1项的的大小关系为s[(i-1)mod K+1].求出L的最大值. 输入 第一行两个正整数,分别表示N和K (N, K <= 500,000).第二行给出N个正整数,第i个正整数表示a[i] (a[i] <= 10^6).第三行给出K个空格隔开关系符号(>.<或=),第i个表示s[i]. 输出 一个正整数,表示L的

降临(线段树优化dp)

降临 选定点i会有代价\(c_i\),如果一个区间j内的点全被选择,就可以获得回报\(p_j\).点数和区间个数\(<1e5\). 还以为是线段树优化网络流(50万个点200万条边看上去很可做的样子毕竟lbn说过网络流20万万条边完全没问题),没想到是个线段树dp. (虽然这两个线段树完全扯不上关系) 用\(f[i][j]\)表示考虑到第i个点,向左最近的尚未选定的点为j时的最大值.那么,i+1可以选也可以不选.不选i时,\(f[i][j]\rightarrow f[i+1][i+1]\).选i

Codeforces 833B 线段树优化 dp

Codeforces  833B  The Bakery 题意: n 个数要分成 k 块,每块的价值是其不同数的个数,问价值和最大是多少. tags: dp[i][j]表示前 j 个数分成 i 块的最大权值和,转移: dp[i][j] = max( dp[i-1][k] + val[k+1][j] ) , k是 1~j . 但这个过程其实并不好转移,要利用累加的特点,用线段树进行优化 (感觉我不看题解是想不到的,2333) 大概就是,对于第 i 层,我们假定已经知道了第 i-1 层,也就是求出了

【8.23校内测试】【贪心】【线段树优化DP】

$m$的数据范围看起来非常有问题??仔细多列几个例子可以发现,在$m<=5$的时候,只要找到有两行状态按位$&$起来等于$0$,就是可行方案,如果没有就不行. #include<iostream> #include<cstdio> #include<cstring> using namespace std; int cnt[1<<4+1], n, m; int main ( ) { freopen ( "prob.in",

理想乡题解 (线段树优化dp)

题面 思路概述 首先,不难想到本题可以用动态规划来解,这里就省略是如何想到动态规划的了. 转移方程 f[i]=min(f[j]+1)(max(i-m,0)<=j<i 且j符合士兵限定) 注意要用 max(i-m,0)以防止越界 我们先用两个数组sl,sa分别统计1~i个士兵中有多少个Lencer和Archer 然后在max(i-m,0)中寻找符合条件的j (1).两种士兵相差不超过k. 这个好说abs((sl[i]-sl[j])-(sa[i]-sa[j]))<=k 不要忘了第二种情况!!

bzoj 1835 基站选址(线段树优化Dp)

Description 题意:有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di 需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立基站的费用为Ci 如果在距离第i个村庄不超过Si的范围内建立了一个通讯基站,那么就成它被覆盖了 如果第i个村庄没有被覆盖,则需要向他们补偿,费用为Wi 现在的问题是,选择基站的位置,使得总费用最小. Solution 首先可以想到dp,用dp[i][j]表示前i个村庄建了j个通讯站且第j个建在i处 dp[i][j]=min(dp[k][

hdu45221——小明系列问题——小明序列 线段树优化dp

小明系列问题--小明序列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1918    Accepted Submission(s): 583 Problem Description 大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了.可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来找