版权声明:本文为博主原创文章,未经博主允许不得转载。 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 四种。
定义状态 表示某个 单词末尾在整个句子中的位置为 时,的种类数。
例如在 abcd 中 ab为 (以 1 为 起始位置)。此题 也可归类为DAG 。以前的状态就是确定当前单词以后,出掉单词长度的一个位置,例如确定 ab后 .
故递推式为:
这题 由于是采用 “逆临边“的形式 递推,所以 很难打印出路径。
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;
}