Ural 1427

PRO IS HERE


描述:将一段文本分成最少的几段,全是由空格和字母组成的最长可拥有m个字符,否则最多含n个字符。

求最少的段数。


我们假设第一种方案是只存储空格和字母,第二种方案为其他。

DP  : dp[i][0] 表示到i这个点且这个点用的是第一种方案的最少的切段。

        dp[i][1] 表示。。。。。。。。。。。。第二种方案。。。。。



然后就可以了。


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;

#define FOR(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define DOR(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define bug puts("Fuck");
#define LL long long
#define pb push_back
#define mp make_pair

#define nMax 101000
#define eps 1e-8
#define inf 0x7fffffff

char s[nMax];
int n,m;
int l[nMax],dp[nMax][2];

int in(char ch){
	return ch==' ' || (ch>='a' && ch<='z') || (ch>='A'&&ch<='Z') ;
}

void sovle(){
	l[0]=0;
	s[0]='.';
	for(int i=1;s[i];i++) if(in(s[i])){
		l[i]=l[i-1];
	}else l[i]=i;
	dp[0][0]=dp[0][1]=0;
	int i;
	for(i=1;s[i];i++) {
		int j=i-n;
		if(j<=0) j=0;
		dp[i][0] = min(dp[j][0],dp[j][1]) + 1;
		if(in(s[i])) {
			int j = l[i];
			if(i-m > j) j=i-m;
			dp[i][1] = min(dp[j][0],dp[j][1]) + 1;
		}else dp[i][1] = inf;
//		printf("%d %d %d \n",i,dp[i][0],dp[i][1]);
	}
	int ans = min(dp[i-1][0],dp[i-1][1]);
	printf("%d\n",ans);
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
#endif

	while(~scanf("%d%d",&n,&m)){
		gets(s);gets(s+1);
		sovle();
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值