码迷,mamicode.com
首页 > 其他好文 > 详细

[HAOI2008]木棍分割

时间:2018-01-01 23:46:56      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:网址   修改   连接   pos   观察   splay   math   check   res   

题目大意

网址:https://daniu.luogu.org/problemnew/show/P2511
题目大意:
有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处,砍完后n根木棍被分成了很多段,
要求满足总长度最大的一段长度最小, 并且输出有多少种砍的方法使得总长度最大的一段长度最小.
数据范围: \(n<=50000, 0<=m<=min(n-1,1000)\).

题目解法

第一问弱智题,直接二分即.
第二问考虑DP。 显然f[i][j]表示到了第i根木棍,已经切了j次的方案数。
那么找到i木棍最远可延展距离lev[i]。显然转移为:
\[f[i][j] = ∑f[v][j-1],(Lg[v,i]<=Res)\]
但是这样子显然空间开不下。
观察到j的转移只于j-1有关,可以压掉j。然后考虑如何优化时间复杂度。
显然f[i][j]求和是可以线性记录的。令:
\[g[i][j-1] = g[i-1][j-1] +∑f[v][j-1],(Lg[v,i]<=Res)\]
那么每次转移时,一边转移f,一边修改g,这样就可以实现\(O(1)\)转移了。
最终的空间复杂度为\(O(N)\),时间复杂度为\(O(N*M)\)

具体代码

#include<bits/stdc++.h>
#define RG register
#define IL inline
#define maxn 100005
#define mod 10007
using namespace std;

int Res,N,M,Ans,Lg[maxn],lev[maxn],f[maxn][3],g[maxn][3];

IL bool Check(RG int x){
    RG int d = 0,cnt = 0;
    for(RG int i = 1; i <= N; i ++){
        if(Lg[i] > x)return false;
        if(d + Lg[i] > x){d = Lg[i]; cnt++;}
        else d += Lg[i];
    }
    return cnt <= M;
}

int main()
{
    cin>>N>>M;
    for(RG int i = 1; i <= N; i ++)cin>>Lg[i];
    int L = 0,R = 2000000000; Res = -1;
    while(L<=R){
        RG int mid = (L+R)>>1;
        if(Check(mid)){Res = mid; R = mid - 1;}
        else L = mid + 1;
    }
    for(RG int i = 1; i <= N; i ++)Lg[i] += Lg[i-1];
    L = 1;
    for(RG int R = 1; R <= N; R ++)
        {while(Lg[R] - Lg[L-1] > Res && L<R)L++ ; lev[R] = L;}
    for(RG int i = 1; i <= N; i ++)
        f[i][0] = (Lg[i] <= Res),g[i][0] = (g[i-1][0] + f[i][0])%mod;
    Ans = (Lg[N] <= Res);
    for(RG int t = 1; t <= M; t ++){
        RG int j = t&1;
        g[0][j] = 0;
        for(RG int i = 1; i <= N; i ++){
            f[i][j] = (g[i-1][j^1] - g[lev[i]-2][j^1] + mod)%mod;
            if(i == N)Ans = (Ans + f[i][j])%mod;
            g[i][j] = g[i-1][j] + f[i][j];
        }
    }
    cout<<Res<<" "<<Ans; return 0;
}

[HAOI2008]木棍分割

标签:网址   修改   连接   pos   观察   splay   math   check   res   

原文地址:https://www.cnblogs.com/GuessYCB/p/8168876.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!