HDU 2577 DP 題解php
2019-11-30c++
Written by WSYide
1.題目傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=2577spa
2.題目思路: 這道題看上去是一道字符串模擬,雖然我最開始也是這樣作的,但正確的作法應該是DP。在你們的認知中,DP應該使用與解決一些相似於石子合併,能量項鍊那樣的題,這道題怎麼會用到DP呢??
code
咱們假設dp[i][0]表示如今沒開大寫鎖定,dp[i][1]表示如今開了大寫鎖定,這樣的話就能夠推出這樣的遞推表達式:blog
dp[i][1]=min(dp[i-1][1]+2,dp[i-1][0]+2); dp[i][0]=min(dp[i-1][1]+2,dp[i-1][0]+1);
哦,對了,這樣幾句話以前還要先判斷這個字符是否是大寫/小寫:ci
bool checksmall(char a) { if(a>='a'&&a<='z') return true; if(a>='A'&&a<='Z') return false;
}
因此通過這樣的更改後的代碼就是這個壓子的:字符串
if(checksmall(a[i-1])) { dp[i][1]=min(dp[i-1][1]+2,dp[i-1][0]+2); //1 capslock dp[i][0]=min(dp[i-1][1]+2,dp[i-1][0]+1); } else { dp[i][1]=min(dp[i-1][1]+1,dp[i-1][0]+2); dp[i][0]=min(dp[i-1][1]+2,dp[i-1][0]+2); }
最後給一個福利:it
#include<bits/stdc++.h> using namespace std; bool checksmall(char a) { if(a>='a'&&a<='z') return true; if(a>='A'&&a<='Z') return false; } int dp[100001][2]; int main() { int n; char a[100001]; scanf("%d",&n); while(n--) { memset(dp,0x3f,sizeof(dp)); cin>>a; int l=strlen(a); dp[0][0]=0; dp[0][1]=1; for(int i=1;i<=l;i++) { if(checksmall(a[i-1])) { dp[i][1]=min(dp[i-1][1]+2,dp[i-1][0]+2); //1 capslock dp[i][0]=min(dp[i-1][1]+2,dp[i-1][0]+1); } else { dp[i][1]=min(dp[i-1][1]+1,dp[i-1][0]+2); dp[i][0]=min(dp[i-1][1]+2,dp[i-1][0]+2); } } //if(cpos==1) ans++; printf("%d\n",min(dp[l][0],dp[l][1]+1)); } return 0; }
謝謝你們!io