哈哈哈没错又是我
还是老规矩,原题
还是思路:
/*
我们用 dp[x]表示长度为 x时最少要给多少钱,如果当前字符串是t的子串.
且当前(也就是代码中的 dp[j])为-1(没被更新过).
或者比加入这个字符串前的最小价值(也就是代码中的 dp[j-k])要大时,就更新 dp[j].
最后的 dp[len](len 是t的长度)就是答案.
*/
AC code:
#include <iostream> // 基本入出力ストリーム
#include <algorithm> // 一般的なアルゴリズム(ソート、ルックアップ、やり直し、二分ルックアップなど)
#include <vector> // 動的配列(スペースが足りないと自動的に拡張されます)
#include <queue> // スタック(先に入って先に出ます)
#include <stack> // スタック(先に入ってから出ます)
#include <set> // 集合(反復しない順序)です
#include <map> // キー値対コンテナ(マッピング)
#include <list> // 両方向リスト
#include <math.h> // すうがくかんすう
#include <functional> // 通用的函数绑定和调用机制一般的なバインディングと呼び出しの仕組み
#include<string.h>
#define endl '\n'
#define pii pair<int, int>
#define pdd pair<double, double>
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
using namespace std;
int n,a,dp[110];
string t,s[110];
void solve() {
//コンテストプログラム
//すべてのコードはこちらに書いてあります
for(int i=1;i<=100;i++) dp[i]=-1;
dp[0]=0;
cin>>t>>n;
int len=t.size();
for(int i=1;i<=n;i++){
cin>>a;
for(int h=1;h<=a;h++) cin>>s[h];
for(int j=len;j>=1;j--){
for(int u=1;u<=a;u++){
int k=s[u].size();
if (j-k>=0&&t.substr(j-k,k)==s[u]&&dp[j-k]!=-1){
int tmp=dp[j-k]+1;
if(dp[j]==-1||dp[j]>tmp) dp[j]=tmp;
}
}
}
}
cout<<dp[len]<<endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t; // 非多组测试数据请注释该行
while(t--) solve();
return 0;
}
(笑
今日推歌:流星群 - gumi