文字游戏 dp

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tianweidadada/article/details/82927686

题目:

给你一份单词表,和一个句子。求出该句子能有多少种不同的划分方法。例如:单词是ab 、cd、 a、 b、 c、 d

句子是abcd。则共有 a/b/c/d、 ab/c/d、a/b/cd、ab/cd 四种。

定义状态dp[i] 表示某个 单词末尾在整个句子中的位置为 i 时,的种类数。

例如在 abcd 中 ab为 dp[2]  (以 1 为 起始位置)。此题 也可归类为DAG 。以前的状态就是确定当前单词以后,出掉单词长度的一个位置,例如确定 ab后  dp[4] = dp[4-len(ab)].

故递推式为:

dp[i] = dp[i] + dp[i-word[j].size()]

这题 由于是采用 “逆临边“的形式 递推,所以 很难打印出路径。

code: 

#include<iostream>
#include<stdio.h>
#include<vector>
#include<map>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
const int N = 105;

string word[N];
string sentence;
int dp[N*10+5];

int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n;
        cin >> n;
        for(int i = 0; i < n; ++i){
            cin >> word[i];
        }
        cin >> sentence;
        fill(dp,dp+N,0);

        dp[0] = 1; // 这里关键
        int len = sentence.size();
        for(int i = 1; i <= len; ++i){
            for(int j = 0; j < n; ++j){
                int pos = sentence.find(word[j]);
                pos += word[j].size();
                if(pos == i){ //只有当前单词后缀位置满足条件时候才可以
                    dp[i] = dp[i] + dp[i-word[j].size()];
                }
            }
        }
        cout << dp[len] << endl;

        return 0;
    }

猜你喜欢

转载自blog.csdn.net/Tianweidadada/article/details/82927686
今日推荐