2012-2013 ACM-ICPC, Asia Tokyo Regional Contest Beautiful Spacing 二分 + dp + 双指针扫描
2017-09-13 20:21
656 查看
题意 : 给你一个含n个单词的文本,按照一些规则放入宽度为w的矩形中,怎样使最大的空格最小。
题解 : 首先我们可以发现答案是满足二分性质的,如果少的空格可以那么多的也一定可以,这样的话我们就可以对答案进行二分,判断一个mid 是否可以成为答案。我们定义dp[i]表示第i个单词能不能当某一行的末尾,这样的话,我们可以定义dp[0] = 1 认为一开始的满足的 (这就是边界条件),dp[i] 肯定是从前面一个1的位置转移过来的,但是直接暴力前面的1的位置的话最坏情况是 n
^ 2 logn的 肯定超时,这个时候我们发现所有的可能解都在一个小区间 (l,r) 内这样我们就可以用双指针扫描这个小区间就可以了。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;
int res[maxn] = {0};
ll len[maxn] = {0};
int dp[maxn] = {0};
ll pre[maxn] = {0};
int cnt = 0;
ll n,m;
ll mid;
ll i;
ll ans = 1000000007;
bool check (ll k) {
ll mi = pre[i] - pre[k] + i - k - 1ll;
ll mx = pre[i] - pre[k] + (i - k - 1ll) * mid;
if (mi <= m && mx >= m) return true;
return false;
}
int main () {
ios_base :: sync_with_stdio(false);
while(cin >> m >> n && n) {
memset (pre,0,sizeof (pre));
for (i = 1;i <= n ; ++ i) {
cin >> len[i];
pre[i] = pre[i - 1] + len[i];
}
int r = m;
int l = 1;
while (r >= l) {
mid = (l + r) >> 1;
memset (dp,0,sizeof (dp));
dp[0] = 1;
cnt = 1;
int start = 0;
int end = 0;
for (i = 1;i <= n; ++ i) {
while (((i - res[end] - 1ll) * mid) + pre[i] - pre[res[end]] > m && end < cnt - 1) {
end ++;
}
for (int j = end;j >= start; -- j) {
if (((i - res[j] - 1) + pre[i] - pre[res[j]]) > m) {
start = j + 1;
break;
}
dp[i] = check(res[j]);
if (dp[i]) {
res[cnt ++] = i;
start = j;
break;
}
}
}
for (i = n;i >= 0;-- i) {
if (dp[i]) {
if ((pre
- pre[i] + n - i - 1) <= m) {
ans = min (ans,mid);
r = mid - 1;
}
else {
l = mid + 1;
}
break;
}
}
}
cout << ans << endl;
ans = 100000007;
}
return 0;
}
题解 : 首先我们可以发现答案是满足二分性质的,如果少的空格可以那么多的也一定可以,这样的话我们就可以对答案进行二分,判断一个mid 是否可以成为答案。我们定义dp[i]表示第i个单词能不能当某一行的末尾,这样的话,我们可以定义dp[0] = 1 认为一开始的满足的 (这就是边界条件),dp[i] 肯定是从前面一个1的位置转移过来的,但是直接暴力前面的1的位置的话最坏情况是 n
^ 2 logn的 肯定超时,这个时候我们发现所有的可能解都在一个小区间 (l,r) 内这样我们就可以用双指针扫描这个小区间就可以了。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define ll long long
using namespace std;
const int maxn = 1e5 + 10;
int res[maxn] = {0};
ll len[maxn] = {0};
int dp[maxn] = {0};
ll pre[maxn] = {0};
int cnt = 0;
ll n,m;
ll mid;
ll i;
ll ans = 1000000007;
bool check (ll k) {
ll mi = pre[i] - pre[k] + i - k - 1ll;
ll mx = pre[i] - pre[k] + (i - k - 1ll) * mid;
if (mi <= m && mx >= m) return true;
return false;
}
int main () {
ios_base :: sync_with_stdio(false);
while(cin >> m >> n && n) {
memset (pre,0,sizeof (pre));
for (i = 1;i <= n ; ++ i) {
cin >> len[i];
pre[i] = pre[i - 1] + len[i];
}
int r = m;
int l = 1;
while (r >= l) {
mid = (l + r) >> 1;
memset (dp,0,sizeof (dp));
dp[0] = 1;
cnt = 1;
int start = 0;
int end = 0;
for (i = 1;i <= n; ++ i) {
while (((i - res[end] - 1ll) * mid) + pre[i] - pre[res[end]] > m && end < cnt - 1) {
end ++;
}
for (int j = end;j >= start; -- j) {
if (((i - res[j] - 1) + pre[i] - pre[res[j]]) > m) {
start = j + 1;
break;
}
dp[i] = check(res[j]);
if (dp[i]) {
res[cnt ++] = i;
start = j;
break;
}
}
}
for (i = n;i >= 0;-- i) {
if (dp[i]) {
if ((pre
- pre[i] + n - i - 1) <= m) {
ans = min (ans,mid);
r = mid - 1;
}
else {
l = mid + 1;
}
break;
}
}
}
cout << ans << endl;
ans = 100000007;
}
return 0;
}
相关文章推荐
- 2012-2013 ACM-ICPC, Asia Tokyo Regional Contest F.Never Wait for Weights(带权并查集模板)
- 2014-2015 ACM-ICPC, Asia Tokyo Regional Contest D題:Space Golf [二分+三分+基础数学]
- The 2013 ACM-ICPC Asia Changsha Regional Contest(2013区域赛练习)
- hdu 4272 LianLianKan ( dp + 状态压缩 2012 ACM/ICPC Asia Regional Changchun Online)
- zoj 3659 Conquer a New Region The 2012 ACM-ICPC Asia Changchun Regional Contest
- 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest H Milestones1 (暴力)
- 2013 ACM/ICPC Asia Regional Changchun Online Problem J & hdu4768 Flyer(二分)
- The 2013 ACM-ICPC Asia Changsha Regional Contest
- The 2013 ACM-ICPC Asia Changsha Regional Contest - A
- hdu 4768 Flyer 二分(2013 ACM/ICPC Asia Regional Changchun Online 1010)
- HDU 3681 Prison Break 二分+搜索 The 35th ACM-ICPC Asia Regional Contest (Hangzhou)
- 2014-2015 ACM-ICPC, Asia Tokyo Regional Contest G題 (线段树区间更新)
- 2012-2013 ACM-ICPC East Central North America Regional Contest (ECNA 2012)
- The 2013 ACM-ICPC Asia Changsha Regional Contest - J
- 2014-2015 ACM-ICPC, Asia Tokyo Regional Contest A题 Bit String Reordering(暴力)
- HDU 5953 Game of Taking Stones(威佐夫博弈+高精度+二分)——The 2016 ACM-ICPC Asia Dalian Regional Contest
- The 2013 ACM-ICPC Asia Changsha Regional Contest C Zoj Collision
- The 2012 ACM-ICPC Asia Changchun Regional Contest(problem B)
- The 2012 ACM-ICPC Asia Changchun Regional Contest(problem E)
- The 2013 ACM-ICPC Asia Changsha Regional Contest K Pocket Cube