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;
}

  

转载于:https://www.cnblogs.com/l609929321/p/9520464.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值