• P1026 统计单词个数


    中文题

    想法:

    其实我觉得这题的细节挺多的。

    首先注意题目中的“每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this 中可包含 this 和 is,选用 this 之后就不能包含 th。”

    这句话其实就要求我们需要倒序去更新而不能正序更新(自行思考),这样处理出各个区间之间单词个数

    然后开始dp

    f[i][k] 代表从1~i 分成 k 段的最大单词数

    然后我们枚举断点去更新状态就好了 f[i][k] = max(f[j][k-1]+s[j+1][i],f[i][k]) 

    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    #include <iostream>
    #include <cstring>
    
    #define LL long long
    #define ls nod<<1
    #define rs (nod<<1)+1
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define INF 0x3f3f3f3f
    
    const double eps = 1e-10;
    const int maxn = 200 + 10;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    int f[maxn][maxn];
    int sum[maxn][maxn];
    string w[maxn],str;
    int n,k,p;
    
    bool check(int l,int r) {
        string x = str.substr(l,r-l+1);
        for (int i = 1;i <= n;i++) {
            if (x.find(w[i]) == 0)
                return true;
        }
        return false;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin >> p >> k;
        str += "0";
        for (int i = 1;i <= p;i++) {
            string s;
            cin >> s;
            str += s;
        }
        cin >> n;
        for (int i = 1;i <= n;i++)
            cin >> w[i];
        int len = str.length()-1;
        for (int j = len;j >= 1;j--) {
            for (int i = j;i >= 1;i--) {
                sum[i][j] = sum[i+1][j];
                if (check(i,j))
                    sum[i][j]++;
            }
        }
        f[0][0] = 0;
        for (int i = 1;i <= k;i++)
            f[i][i] = f[i-1][i-1] + sum[i][i];
        for (int i = 1;i <= len;i++)
            f[i][1] = sum[1][i];
        for (int i = 1;i <= len;i++) {
            for (int j = 1;j <= k && j < i;j++) {
                for (int l = j-1;l < i;l++)
                    f[i][j] = max(f[i][j],f[l][j-1]+sum[l+1][i]);
            }
        }
        cout << f[len][k] << endl;
        return 0;
    }
  • 相关阅读:
    继续尝试,在Community Server添加一个页面二
    终于可以Blog了
    额的娘咧!从哪里下手啊!
    你可能肯定没有尝试中西合壁
    oracle11g常用bug故障排查步骤
    oracle11g dataguard完全手册2switchover
    oracle11g dataguard 完全手册
    oracle外部表 初探
    使用Deinstall专用工具删除Oracle Database
    oracle11g dataguard完全手册3failover &active dataguard(完)
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12489584.html
Copyright © 2020-2023  润新知