HAOI 2008 木棍分割

阅读: 评论:0

HAOI 2008 木棍分割

HAOI 2008 木棍分割

//需要优化很多的DP,包括预处理前缀和,滚动数组,预处理可转移状态 
#include<bits/stdc++.h>
using namespace std;
const int moder = 10007;
const int maxn = 50010;
const int inf = 0x3f3f3f3f;
int n, m, tmp;
int f[maxn], a[maxn], last[maxn], tot[maxn], sum[maxn];inline bool check(int mid){int tot = 0, final = 0;for(int i = 1; i <= n; i++){if(tot + a[i] <= mid)    tot += a[i];else if(a[i] <= mid)    tot = a[i], final++;else if(a[i] > mid)    return 0;if(final > m)    return 0;}if(final == m)    return 1;
}int main(){scanf("%d%d", &n, &m);int mina = inf;for(int i = 1; i <= n; i++){scanf("%d", &a[i]);mina = min(a[i], mina);sum[i] = sum[i-1] + a[i];}int ans;int l = mina, r = sum[n] + 1;while(l < r){int mid = l + r >> 1;if(check(mid)){ans = mid;r = mid;}else l = mid + 1;}//第一问二分 for(int i = 1; i <= n; i++){if(sum[i] <= ans)    f[i] = 1;//预处理ans从开始能到的状态 else break;}for(int i = 1; i <= n; i++)tot[i] = (tot[i-1] + f[i]) % moder;//预处理前缀和 int now = 0;for(int i = 1; i <= n; i++){while(1){if(sum[i] - sum[now] <= ans)    break;else now++;}last[i] = now-1;//找每个i符合条件的转移状态 }for(int i = 1; i <= m; i++){for(int j = 1; j <= n; j++)f[j] = (tot[j-1] - tot[last[j]] + moder) % moder;for(int j = 1; j <= n; j++)tot[j] = tot[j-1] + f[j];tmp = (tmp + f[n]) % moder;//至多m次,所以每次都转移 }printf("%d %dn", ans, tmp);return 0;
}

本文发布于:2024-02-02 11:08:42,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170684332043390.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:木棍   HAOI
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23