题目大意是:给你一串字符串,然后让你去截看看最少能截成几分。如果只包含大小写字母和空格就可以最多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; }