P1026 統計單詞個數 [dp]
阿新 • • 發佈:2019-01-30
sum line bstr sin rip 個數 第一個 math length 個字符串,所以至少要從\(k\)開始。
P1026 統計單詞個數
這道題看上去就是要用dp的樣子。裸裸的dp題無誤。
首先要把分開的字符串合成那個長度小於等於\(200\)的總字符串。
然後做個預處理,預處理出任意區間內的單詞個數,設為\(sum[i][j]\)。
有一個神奇的地方:
當選用一個單詞之後,其第一個字母不能再用。
題解裏面有這麽一種解決方式:
倒序枚舉\(j\)和\(i\)。初始化\(sum[i][j] = sum[i + 1][j]\)。如果子串中從一開始就存在單詞,加1。
其實不怎麽知道原理這種做法還剛好滿足了上面的限制。
然後套上一種區間dp的思路,3重枚舉更新dp。
因為若要分\(k\)段,則至少也要已經遍歷過\(k\)
代碼:
/************************************************************************* @Author: Garen @Created Time : Tue 29 Jan 2019 09:56:30 PM CST @File Name: P1026.cpp @Description: ************************************************************************/ #include<bits/stdc++.h> using std::cin; using std::cout; using std::endl; using std::string; #define ll long long const int maxn = 205; string str; string word[8]; int dp[maxn][maxn]; int pd[maxn]; int p, m, s, n; int sum[maxn][maxn]; int check(int l, int r) { l--; r--; string ch = str.substr(l, r - l + 1); for(int i = 1; i <= s; i++) { if(ch.find(word[i]) == 0) return 1; } return 0; } int main() { cin >> p >> m; string temp; while(p--) { cin >> temp; str = str + temp; n += temp.length(); } cin >> s; for(int i = 1; i <= s; i++) cin >> word[i]; for(int j = n; j >= 1; j--) { for(int i = j; i >= 1; i--) { sum[i][j] = sum[i + 1][j] + check(i, j); } } for(int i = 1; i <= m; i++) dp[i][i] = dp[i - 1][i - 1] + sum[i][i]; for(int i = 1; i <= n; i++) dp[i][1] = sum[1][i]; for(int i = 1; i <= n; i++) { for(int j = 2; j <= m && j < i; j++) { for(int k = j; k < i; k++) { dp[i][j] = std::max(dp[i][j], dp[k][j - 1] + sum[k + 1][i]); } } } cout << dp[n][m] << endl; return 0; }
P1026 統計單詞個數 [dp]