URAL 1427. SMS (线性dp)

题目大意是:给你一串字符串,然后让你去截看看最少能截成几分。如果只包含大小写字母和空格就可以最多m个截成一个,有其他的字符那就最多n个截成一个。

数据很多直接dp[i][j]空间与时间都不能承受。dp[i][0]表示只有字母和空格,dp[i][1]表示有其他的字符。vis[i][0],vis[i][1]动态的记录长度。时间就会降为O(n)空间降为2*n。

1427. SMS

Time limit: 0.5 second

Memory limit: 64 MB

Background

Mobile technologies are going to become a part of our life. So many times you have read this sentence in advertisements and magazine articles. So many times you have heard it from fattened IT corporations
presidents who grab money of deceived investors and from managers of mobile phones shops who try to sell useless smartphones at the cost of $500 a piece... Sleep tight. The age of mobility has not begun yet. Believe me, you will feel when it comes to life.

One day it will be felt by the millions of people who would find their mobile phones full of dozens of SMS messages offering sweets with swastika, courses of american Russian, services of famous charlatan
Ilya German and participation in forthcoming contests on Timus Online Judge. Unfortunately the history will not keep the name of one modest programmer who was in the very origin of new age technology which will be known soon as SMS-spam. But I will say something
else. This programmer is you.

Problem

SMS-spam is a promising technology of mass delivery of text advertisements by means of SMS messages. Very convenient, very effective, very easy. Not so easy, however. The problem is the length of one
SMS message is limited while advertisements are usually rather long. Fortunately, an advertisement can be divided into several parts, and each part will be sent as a separate SMS message.

But here greedy mobile operators enter the game, because they also want to get some money. Their acquisitiveness is expressed in the fact that each delivered SMS message must be paid for. So an advertisement
should be delivered to a thankful recipient by means of minimal number of SMS messages.

And the last thing. Quirky mobile operators have invented an amusing feature for people who want to save some money. SMS message which consists of latin letters and spaces only can be up to M characters
long while the length of SMS message which consists of any characters is limited by N characters.

Input

The first line contains the integer numbers N and M (1 ≤ N ≤ M ≤ 10000). The second line contains an advertisement. The advertisement consists of from 1 to 100000 characters. Each character is either
a latin letter, a space, a digit or a punctuation mark "." (full stop), "," (comma), ";" (semicolon), ":" (colon), "!" (exclamation mark), "?" (question mark), "-" (hyphen) or """ (double quotes). The advertisement is terminated by the end of line.

Output

You should output the minimal number of SMS messages required to deliver the advertisement.

Sample

input
10 15
On the 11-th of February, 2006 the contest "Timus Top Coders: First Challenge" is held!
output
8
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-12
///#define M 1000100
#define LL __int64
///#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)

using namespace std;

const int maxn = 100010;

int dp[maxn][2];
int vis[maxn][2];

int judge(char s)
{
    if(s == ' ') return 1;
    if(s <= 'Z' && s >= 'A') return 1;
    if(s <= 'z' && s >= 'a') return 1;
    return 0;
}

char str[maxn];

int main()
{
    int n, m;
    while(cin >>n>>m)
    {
        memset(dp, 0, sizeof(dp));
        memset(vis, 0, sizeof(vis));
        getchar();
        gets(str);
        int len = strlen(str);
        dp[0][1] = 1;
        vis[0][1] = 1;
        if(judge(str[0]))
        {
            dp[0][0] = 1;
            vis[0][0] = 1;
        }
        else
        {
            dp[0][0] = -1;
            vis[0][0] = 0;
        }
        for(int i = 1; i < len; i++)
        {
            if(judge(str[i]))
            {
                if(vis[i-1][0] >= m)
                {
                    dp[i][0] = min(dp[i-1][1], dp[i-1][0])+1;
                    vis[i][0] = 1;
                }
                else
                {
                    if(vis[i-1][0] && dp[i-1][0] < dp[i-1][1]+1)
                    {
                        dp[i][0] = dp[i-1][0];
                        vis[i][0] = vis[i-1][0]+1;
                    }
                    else
                    {
                        dp[i][0] = dp[i-1][1]+1;
                        vis[i][0] = 1;
                    }
                }
            }
            else
                vis[i][0] = 0;
            if(vis[i-1][1] >= n)
            {
                if(vis[i-1][0]) dp[i][1] = min(dp[i-1][1], dp[i-1][0])+1;
                else dp[i][1] = dp[i-1][1]+1;
                vis[i][1] = 1;
                continue;
            }
            if(!vis[i-1][0] || dp[i-1][1] < dp[i-1][0]+1)
            {
                dp[i][1] = dp[i-1][1];
                vis[i][1] = vis[i-1][1]+1;
                continue;
            }
            dp[i][1] = dp[i-1][0]+1;
            vis[i][1] = 1;
        }
        if(vis[len-1][0]) cout<<min(dp[len-1][0], dp[len-1][1])<<endl;
        else cout<<dp[len-1][1]<<endl;
    }
    return 0;
}
时间: 2024-10-12 02:23:41

URAL 1427. SMS (线性dp)的相关文章

uva 11584 Partitioning by Palindromes 线性dp

// uva 11584 Partitioning by Palindromes 线性dp // // 题目意思是将一个字符串划分成尽量少的回文串 // // f[i]表示前i个字符能化成最少的回文串的数目 // // f[i] = min(f[i],f[j-1] + 1(j到i是回文串)) // // 这道题还是挺简单的,继续练 #include <algorithm> #include <bitset> #include <cassert> #include <

uva 11552 Fewest Flops 线性dp

// uva 11552 Fewest Flops // // 二维线性dp // // 首先,在该块必须是相同的来信.首先记录每块有很多种书 // 称为是counts[i]; // // 订购f[i][j]它代表前i字母j为结尾的最小分块数 // // 假设第i块的開始字母与第i-1块的结束字母同样 // f[i][j] = min(f[i][j],f[i-1][k] + counts[i] - 1); // // 否则 // // f[i][j] = min(f[i][j],f[i-1][k

poj3267——线性dp

poj3267——线性dp The Cow Lexicon Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8458   Accepted: 3993 Description Few know that the cows have their own dictionary with W (1 ≤ W ≤ 600) words, each containing no more 25 of the characters 'a'

线性DP POJ2279 Mr.Young&#39;s Picture Permutations

Mr. Young's Picture Permutations Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1128   Accepted: 562 Description Mr. Young wishes to take a picture of his class. The students will stand in rows with each row no longer than the row behin

HDU 5074 Hatsune Miku (线性dp)

Hatsune Miku Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 471 Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan

Codeforces 176B (线性DP+字符串)

题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成新串.问经过K次变形后,与目标串相同的变形方案数.mod 1000000007. 解题思路: 奇葩的字符串DP.照着别人的题解写的,解释不出原理是什么. 首先统计出经过1次变形,就能和目标串相同的中间产物串(包含源串)的个数cnt.len表示源串长度,那么len-cnt就表示和目标串不同的个数. 用

LightOJ1044 Palindrome Partitioning(区间DP+线性DP)

问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时候要枚举,这样时间复杂度是不可行的. 然后我就想降维度了,只能线性DP,dp[i]表示子串[0,i]的答案.这样可以从i-1转移到i,str[i]单独作一段或者str[i]能和前面的组成回文串,方程如下: dp[i]=min(dp[i-1]+1,dp[j-1]+1) (子串[j,i]是回文串) 现在

POJ 1958 Strange Towers of Hanoi (线性dp,记忆化搜索)

JQuery工具方法. (1)$.isNumeric(obj) 此方法判断传入的对象是否是一个数字或者可以转换为数字. isNumeric: function( obj ) { // parseFloat NaNs numeric-cast false positives (null|true|false|"") // ...but misinterprets leading-number strings, particularly hex literals ("0x...&

LA 4256 Salesmen 线性dp

// LA 4256 Salesmen 线性dp // // 像LCS和LIS问题类似,因为每次修改一个值,都是根据 // 前一个值决定的,那么最后一个结尾的数字肯定要作为 // 状态,而长度作为状态是一目了然的 // // d[i][j]表示长度为i,最后以j结尾的数组修改的最小次数 // // 则状态转移方程为 // // d[i][j] = min(d[i][j],d[i-1][k]+(j,k是否相同或者相邻?0:1)); // // 个人感觉还是比较明显的,最后的答案就是min(d[L]