您的位置:首页 > 其它

URAL 1427. SMS(DP+单调队列)

2013-09-11 18:52 483 查看
题目链接

我用的比较传统的办法。。。单调队列优化了一下,写的有点搓,不管怎样过了。。。两个单调队列,存两个东西,预处理一个标记数组存。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <algorithm>
using namespace std;
#define INF 1000000
char str[200000];
int dp[200000];
int pre[200000];
int que1[200000];
int que2[200000];
int judge(char s)
{
if(s <= 'Z'&&s >= 'A')
return 1;
else if(s <= 'z'&&s >= 'a')
return 1;
else if(s == ' ')
return 1;
else
return 0;
}
int main()
{
int n,m,i,j,len,str1,end1,str2,end2;
scanf("%d%d%*c",&n,&m);
gets(str);
len = strlen(str);
for(i = 0; i < len; i ++)
{
if(judge(str[i]))
{
for(j = i; j < len; j ++)
{
if(judge(str[j]))
pre[j] = i;
else
{
i = j;
break;
}
}
if(j == len) break;
}
}
for(i = 1;i <= len;i ++)
dp[i] = INF;
str1 = 0;end1 = 1;
str2 = 0;end2 = 1;
que1[0] = que2[0] = 0;
for(i = 1;i <= len;i ++)
{
dp[i] = dp[que1[str1]] + 1;
if(judge(str[i-1]))
{
if(str2 < end2)
dp[i] = min(dp[i],dp[que2[str2]]+1);
}
else
{
str2 = end2 = 0;
}
if(i == len) continue;
while(str1 < end1&&dp[i] <= dp[que1[end1-1]])
end1 --;
que1[end1++] = i;
while(str1 < end1&&i - que1[str1] >= n)
str1 ++;
if(judge(str[i]))
{
while(str2 < end2&&dp[i] <= dp[que2[end2-1]])
end2 --;
que2[end2++] = i;
while(str2 < end2&&que2[str2] < pre[i])
str2 ++;
while(i - que2[str2] >= m&&str2 < end2)
str2 ++;
}
}
printf("%d\n",dp[len]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: