hdu6376 度度熊剪纸条 思维

度度熊剪纸条

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1788    Accepted Submission(s): 318


Problem Description
度度熊有一张纸条和一把剪刀。

纸条上依次写着 N 个数字,数字只可能是 0 或者 1

度度熊想在纸条上剪 K 刀(每一刀只能剪在数字和数字之间),这样就形成了 K+1 段。

他再把这 K+1 段按一定的顺序重新拼起来。

不同的剪和接的方案,可能会得到不同的结果。

度度熊好奇的是,前缀 1 的数量最多能是多少。
 

 

Input
有多组数据,读到EOF结束。

对于每一组数据,第一行读入两个数 N 和 K 。

第二行有一个长度为 N 的字符串,依次表示初始时纸条上的 N 个数。

0K<N10000

所有数据 N 的总和不超过100000
 

 

Output
对于每一组数据,输出一个数,表示可能的最大前缀 1 的数量。
 

 

Sample Input
5 1 11010 5 2 11010
 

 

Sample Output
2 3
 

 

Source
 

 

Recommend
chendu   |   We have carefully selected several similar problems for you:  6437 6436 6435 6434 6433 
 
分析:求可能的最大前缀,首先我们把所有连续的1分离出来,考虑分离中间的连续1我们要进行两次操作,分离最前面和最后面的连续的1只要一次操作
  当k大于2的时候,我们直接加上最大的连续的1,当k<=2时,特判分离需要1次和两次的和的较大值
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define ls (r<<1)
#define rs (r<<1|1)
#define debug(a) cout << #a << " " << a << endl
using namespace std;
typedef long long ll;
const ll maxn = 1e4+10;
const ll mod = 998244353;
const double pi = acos(-1.0);
const double eps = 1e-8;
ll n, k, a[maxn];
bool cmp( ll p, ll q ) {
    return p > q;
}
int main() {
    ios::sync_with_stdio(0);
    while( cin >> n >> k ) {
        string s;
        cin >> s;
        bool flag = false;
        ll cnt = 0, j = 0, st = 0, ed = n-1, num1 = 0, num2 = 0, ans = 0;
        while(s[st]=='1'&&st<n) {
            st ++;
        }
        num1 = st;
        while(s[ed]=='1'&&st<=ed) {
            ed --;
        }
        num2 = n-1-ed;
        if( k == 0 ) {
            cout << num1 << endl;
            continue;
        }
        for( ll i = st; i <= ed; i ++ ) {
            if(s[i]=='0') {
                if(cnt) {
                    a[++j] = cnt;
                }
                cnt = 0;
            } else {
                cnt ++;
            }
        }
        sort(a+1,a+j+1);
        ll x = 0;
        while( k > 2 && j >= 1 ) {
            ans += a[j--];
            k -= 2;
        }
        if( k == 1 ) {
            ans += max(num1+num2,a[j]);
        } else {
            ans += max(num1+num2,max(num1+a[j],num2+a[j]));
        }
        cout << ans << endl;
    }
    return 0;
}

  

posted on 2018-08-22 21:20  九月旧约  阅读(207)  评论(0编辑  收藏  举报

导航