国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【BZOJ 1044】[HAOI2008]木棍分割

2019-11-08 03:04:50
字體:
來源:轉載
供稿:網友

思路:

首先二分的答案,算出切m下,最長的一段的最短值。 用動態規劃求方案數。 設f[i][j]表示切了i次,使用到了前j個木段的方案數。 狀態轉移方程: f[i][j]=∑f[i?1][k]→(1≤k≤j?1)(sum[j]?sum[k]≤ans) 對于初始的條件,顯然有f[0][1]=1 不難發現,k是隨著j的增長遞增的,所以用two pointer維護即可。 對于空間,第一維的顯然可以滾掉。

代碼:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 50010;const int p = 10007; int n, m, sm, mx;int val[maxn], sum[maxn];int f[2][maxn];bool check(int x){ int res = 0, tmp = 0; for(int i = 1; i <= n; i ++){ if(tmp + val[i] <= x) tmp += val[i]; else tmp = val[i], res ++; } return res <= m;}int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) scanf("%d", &val[i]), sm += val[i], mx = max(mx, val[i]); for(int i = 1; i <= n; i ++) sum[i] = sum[i-1] + val[i]; int l = mx, r = sm, ans = 0; while(l <= r){ int mid = (l+r) >> 1; if(check(mid)) ans = mid, r = mid - 1; else l = mid + 1; } int now = 0, res = 0; for(int i = 1; sum[i] <= ans; i ++) f[now][i] = 1; for(int i = 1; i <= m; i ++){ int ll = 0, rr = 0, x = 0; now ^= 1; for(int j = 1; j <= n; j ++){ while(rr < j-1) x = ((x+f[now^1][++rr])%p+p)%p; while(sum[j]-sum[ll] > ans) x = ((x-f[now^1][ll++])%p+p)%p; f[now][j] = x; } res = (res+f[now][n])%p; }
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 古蔺县| 紫阳县| 江源县| 平乐县| 江阴市| 罗田县| 兴国县| 六安市| 新平| 鸡东县| 嘉义市| 同心县| 寿光市| 桦川县| 江源县| 泽州县| 白银市| 英山县| 保定市| 临漳县| 通道| 岳西县| 西宁市| 顺平县| 申扎县| 浦东新区| 会宁县| 高平市| 鲁山县| 开封市| 平泉县| 武山县| 泉州市| 沙洋县| 麦盖提县| 广州市| 富源县| 奉贤区| 师宗县| 武威市| 开平市|