題目描述html
輸入編程
輸出spa
樣例輸入code
6
a 1
b 4
d 2
x 3
f 1
e 3
fxeeabadd
2
aba
ed
htm
樣例輸出blog
16字符串
題解get
區間dpstring
同 bzoj2121 ,只不過給出的是字符串總長限制,所以設狀態時須要將全部串壓成一個串,中間用空字符隔開。轉移時直接dp新串的位置。it
權值只須要在統計答案時加上。
具體見代碼吧。
#include <cstdio> #include <cstring> #include <algorithm> #define N 155 using namespace std; int a[26] , ans[N] , pos[N]; char str[N] , w[N] , tmp[3]; bool f[N][N] , g[N][N][N << 1]; int main() { int t , n , m , x , len , l , r , i , j , sum = 0; scanf("%d" , &t); while(t -- ) scanf("%s%d" , tmp , &x) , a[tmp[0] - 'a'] = x; scanf("%s%d" , str + 1 , &m) , n = strlen(str + 1); for(i = 1 ; i <= n ; i ++ ) sum += a[str[i] - 'a']; pos[0] = -1; for(i = 1 ; i <= m ; i ++ ) scanf("%s" , w + pos[i - 1] + 2) , pos[i] = strlen(w + pos[i - 1] + 2) + pos[i - 1] + 1; for(i = 1 ; i <= n ; i ++ ) { f[i][i - 1] = 1; for(j = 0 ; j < m ; j ++ ) g[i][i - 1][pos[j] + 1] = 1; } for(len = 1 ; len <= n ; len ++ ) { for(l = 1 ; l <= n - len + 1 ; l ++ ) { r = l + len - 1; for(i = 0 ; i <= pos[m] ; i ++ ) { if(str[r] == w[i]) g[l][r][i] |= g[l][r - 1][i - 1]; for(j = l ; j <= r ; j ++ ) g[l][r][i] |= g[l][j - 1][i] & f[j][r]; } for(i = 1 ; i <= m ; i ++ ) f[l][r] |= g[l][r][pos[i]]; } } for(i = 1 ; i <= n ; i ++ ) { ans[i] = ans[i - 1] + a[str[i] - 'a']; for(j = 1 ; j <= i ; j ++ ) if(f[j][i]) ans[i] = min(ans[i] , ans[j - 1]); } printf("%d\n" , sum - ans[n]); return 0; }