題目連結:http://codeforces.com/problemset/problem/180/C
題意:
給你一個字串s,長度為n。
讓你將這個字串變成“前面一段都是大寫字母,後面一段都是小寫字母”的形式。
(也可以全是大寫或全是小寫)
問你最少改動幾個字元。
題解:
表示狀態:
dp[i][0/1] = min changes
表示考慮到第i個字元,s[i]改成了大寫(1)或小寫(0)時的最小代價
找出答案:
ans = min(dp[n][0], dp[n][1])
如何轉移:
dp[i][1] = dp[i-1][1] + is_lower(s[i])
dp[i][0] = min(dp[i-1][0], dp[i-1][1]) + is_upper(s[i])
邊界條件:
dp[i][0] = dp[i][1] = 0
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #define MAX_N 100005 5 6 using namespace std; 7 8 int n; 9 int dp[MAX_N][2]; 10 char s[MAX_N]; 11 12 int is_lower(char c) 13 { 14 return ('a'<=c && c<='z') ? 1 : 0; 15 } 16 17 int is_upper(char c) 18 { 19 return ('A'<=c && c<='Z') ? 1 : 0; 20 } 21 22 int main() 23 { 24 scanf("%s",s+1); 25 n=strlen(s+1); 26 memset(dp,0,sizeof(dp)); 27 for(int i=1;i<=n;i++) 28 { 29 dp[i][1]=dp[i-1][1]+is_lower(s[i]); 30 dp[i][0]=min(dp[i-1][0],dp[i-1][1])+is_upper(s[i]); 31 } 32 cout<<min(dp[n][0],dp[n][1])<<endl; 33 }