Problem:
文字列の魔法
魔法使いであるあなたは，今日も魔法の修行に励んでいる．あなたは今，手元に英小文字からなる文字列
X
を持っている．あなたの今日の修行の課題は，この文字列を，別の文字列
Y
に変化させることである．
あなたは，文字列を変化させる魔法を 4 種類習得していて，それらを好きな順序で何回でも唱えることができる．ただし，魔法を唱えるたびに，魔法石と呼ばれる特別な石を消費する．あなたが習得している魔法は次の通りである．
魔法石を
A
個消費する．手元の文字列の好きな位置に，好きな英小文字 1 文字を追加する．例えば，元の文字列が bcbd であった場合，abcbd, bcebd, bcbdf などの文字列に変化させることができる．
魔法石を
E
個消費する．手元の文字列の好きな 1 文字を取り除く．例えば，元の文字列が bcbd であった場合，cbd, bbd, bcd, bcb のいずれかに変化させることができる．なお，元の文字列の長さが 0 である場合，この魔法を唱えることはできない．
魔法石を
S
個消費する．手元の文字列の好きな 1 文字を，別の好きな英小文字 1 文字に置き換える．例えば，元の文字列が bcbd であった場合，acbd や bebd などの文字列に変化させることができる．なお，元の文字列の長さが 0 である場合，この魔法を唱えることはできない．
魔法石を
R
個消費する．手元の文字列の先頭の 1 文字を末尾に移動させる．例えば，元の文字列が bcbd であった場合，cbdb に変化させることができる．なお，元の文字列の長さが 0 である場合，この魔法を唱えることはできない．
魔法石は高価なので，あなたは魔法石の消費を最小限にしたいと考えている．文字列
X
を文字列
Y
に変化させるために必要な魔法石の個数の最小値を求めよ．
Input
入力は複数のデータセットからなる．各データセットは以下の形式で表される．
X
Y
A
E
S
R
X
,
Y
は英小文字のみからなる異なる文字列であり，いずれも長さは
1
以上
100
以下である．
A
,
E
,
S
,
R
はいずれも
1
以上
10
6
以下の整数である．
入力の終わりは '#' 一つのみからなる行で示される．入力に含まれるデータセットの数は高々 50 である．
Output
各データセットについて，文字列
X
を文字列
Y
に変化させるために必要な魔法石の個数の最小値を，1 行に出力せよ．
Sample Input
typewriter
periodicity
100010
100100
101000
110000
periodicity
typewriter
100010
100100
101000
110000
periodicity
typewriter
100010
100100
101000
1
domestic
contest
100010
100100
101000
110000
#
Output for the Sample Input
823120
1001540
603217
502210

Submitted solutions:

code_snippet: #include "bits/stdc++.h"

using namespace std;

#define int long long

const int INF = 1e18;

signed main() {
//    freopen("in.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    while (true) {
        string x, y;
        cin >> x;
        if (x == "#") {
            break;
        }
        cin >> y;
        int n = x.size(), m = y.size();
        int a, e, s, r;
        cin >> a >> e >> s >> r;
        int ans = INF, cur = 0;
        for (int k = 0; k < n; k++) {
            vector<vector<int>> dp(n + 1, vector<int>(m + 1, INF));
            dp[0][0] = 0;
            for (int i = 1; i <= n; i++) {
                dp[i][0] = i * e;
            }
            for (int j = 1; j <= m; j++) {
                dp[0][j] = j * a;
            }
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                    if (x[i - 1] == y[j - 1]) {
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                    int price = (i <= n - k ? e : e - r);
                    dp[i][j] = min({dp[i][j], dp[i - 1][j] + price, dp[i][j - 1] + a, dp[i - 1][j - 1] + s});
                }
            }
            ans = min(ans, dp[n][m] + cur);
            cur += r;
            string x1;
            for (int i = 1; i < n; i++) {
                x1 += x[i];
            }
            x1 += x[0];
            swap(x, x1);
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 70
memory_kb: 3532
final_rank: 19

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

// #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG // 配列外参照のエラー
// #endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vvvvi = vector<vector<vector<vector<int>>>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vvvl = vector<vector<vector<ll>>>;
using vvvvl = vector<vector<vector<vector<ll>>>>;

template <class T> using prique = priority_queue<T>;
template <class T> void chmin(T &a, T b) {
    if (a > b)
        a = b;
}
template <class T> void chmax(T &a, T b) {
    if (a < b)
        a = b;
}

#define all(v) v.begin(), v.end()

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int INF32 = 2e9;
ll INF64 = 9e18;
#define endl '\n';

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

inline void Yes(bool f);

void rotation(string &X) {
    string ret = "";
    ret+=X.back();
    for (int i = 0; i < X.size() - 1; i++) {
        ret += X[i];
    }
    swap(ret, X);
}

///////////////////ここから//////////////////////
bool solve() {
    string X;
    cin >> X;
    if (X == "#") {
        return false;
    }

    string Y;
    cin >> Y;

    reverse(all(X));
    reverse(all(Y));
    ll A, E, S, R;
    cin >> A >> E >> S >> R;
    int N = X.size(), M = Y.size();
    ll ans = INF64;

    for (int rot = 0; rot < N; rot++) {
        //print(X);
        ll cost = R * rot;
        vvl dp(N + 1, vl(M + 1, INF64));
        dp[0][0] = 0;
        for (int i = 0; i < N + 1; i++) {
            for (int j = 0; j < M + 1; j++) {
                ll val = dp[i][j];
                if (i < N) {
                    if (i < rot) {
                        chmin(dp[i + 1][j], val + E - R);
                    } else {
                        chmin(dp[i + 1][j], val + E);
                    }
                }
                if (j < M) {
                    chmin(dp[i][j + 1], val + A);
                }
                if (i < N && j < M) {
                    if (X[i] == Y[j]) {
                        chmin(dp[i + 1][j + 1], val);
                    }
                    chmin(dp[i + 1][j + 1], val + S);
                }
            }
        }
        chmin(ans, dp[N][M]+cost);

        rotation(X);
    }
    print(ans);

    return true;
}

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (solve())
        ;
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ALL(x) (x).begin(),(x).end()
#define REP(i, n) for(ll i=0; i<(ll)(n); i++)
#define PER(i, n) for(ll i=(ll)(n)-1; i>=0; i--)

template<typename T> int LB(const vector<T>& v, T x) { return lower_bound(ALL(v),x)-v.begin(); }
template<typename T> int UQ(T& v) { sort(ALL(v)); v.erase(unique(ALL(v)),v.end()); return v.size(); }
template<typename T> bool chmax(T &a, T b) { return a<b ? a=b, true : false; }
template<typename T> bool chmin(T &a, T b) { return a>b ? a=b, true : false; }
template<typename T> using rpriority_queue = priority_queue<T,vector<T>,greater<T>>;
using ll=long long; const int INF=1e9+10; const ll INFL=4e18;
using ld=long double; using lll=__int128_t; using ull=unsigned long long;
using VI=vector<int>; using VVI=vector<VI>; using VL=vector<ll>; using VVL=vector<VL>;
using PL=pair<ll,ll>; using VP=vector<PL>; using WG=vector<vector<pair<int,ll>>>;


#ifdef LOCAL
#include "./debug.hpp"
#else
#define debug(...)
#define print_line
#endif


//----------------------------------------------------------


bool solve() {
    string X,Y; cin>>X>>Y;
    if(X=="#") return false;

    ll N=X.size(), M=Y.size();
    ll A,E,S,R; cin>>A>>E>>S>>R;

    ll ans=INFL;
    REP(t,N) {
        //dp[i][j]:=X[0,i), Y[0,j)までが一致しているときの最小コスト
        VVL dp(N+1,VL(M+1,INFL)); dp[0][0]=0;

        REP(i,N+1) REP(j,M+1) {
            if(i<N-t) {
                if(i<N && j<M && X[i]==Y[j]) {
                    chmin(dp[i+1][j+1],dp[i][j]);
                }
                if(i<N && j<M) {
                    chmin(dp[i+1][j+1],dp[i][j]+S);
                }
                if(i<N) {
                    chmin(dp[i+1][j],dp[i][j]+E);
                }
                if(j<M) {
                    chmin(dp[i][j+1],dp[i][j]+A);
                }
            } else {
                if(i<N && j<M && X[i]==Y[j]) {
                    chmin(dp[i+1][j+1],dp[i][j]+R-E);
                }
                if(i<N && j<M) {
                    chmin(dp[i+1][j+1],dp[i][j]+R-E+S);
                }
                if(i<N) {
                    chmin(dp[i+1][j],dp[i][j]);
                }
                if(j<M) {
                    chmin(dp[i][j+1],dp[i][j]+A);
                }
            }
        }

        ll res=dp.back().back()+E*t;
        chmin(ans,res);

        X.push_back(X.front());
        X.erase(X.begin());
    }

    cout<<ans<<'\n';
    return true;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);
    cerr << fixed << setprecision(15);
    while (true) {
        if (!solve()) {
            break;
        }
    }
}
accuracy: 1
time_ms: 60
memory_kb: 3428
final_rank: 15

code_snippet: #include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <cctype>
#include <climits>
#include <functional>
#include <cassert>
#include <numeric>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n) - 1; i >= 0; i--)
using ll = long long;
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
constexpr int mod = 1000000007;
using namespace std;
template<class T, class U>
bool chmax(T &a, const U &b){ return a < b ? (a = b, 1) : 0; }
template<class T, class U>
bool chmin(T &a, const U &b){ return a > b ? (a = b, 1) : 0; }
int main(){
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  while(true){
    string s,t;
    cin >> s;
    if(s == "#") break;
    int a,e,S,r;
    cin >> t >> a >> e >> S >> r;
    const int n = s.size();
    const int m = t.size();
    int ans = mod;
    rep(rot, n){
      vvi dp(n + 1, vi(m + 1, mod));
      dp[0][0] = 0;
      rep(i, n+1) rep(j, m+1){
        // insert
        if(j+1 <= m) chmin(dp[i][j+1], dp[i][j] + a);
        // remove
        if(i+1 <= n){
          if(i >= n-rot) chmin(dp[i+1][j], dp[i][j] + e - r);
          else chmin(dp[i+1][j], dp[i][j] + e);
        }
        // edit or thru
        if(i+1 <= n && j+1 <= m) chmin(dp[i+1][j+1], dp[i][j] + (s[i] == t[j] ? 0 : S));
      }
      for(int i = n-rot; i <= n; i++){
        chmin(ans, dp[i][m] + (i-(n-rot))*r + (n-i)*e);
      }
      s.push_back(s[0]);
      s.erase(s.begin());
    }
    cout << ans << "\n";
  }
}
accuracy: 1
time_ms: 40
memory_kb: 3584
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
//#include <atcoder/all>
//using namespace atcoder;
//using mint = modint998244353;

//多倍長整数//
//#include <boost/multiprecision/cpp_int.hpp>
//namespace mp = boost::multiprecision;
//using bint = mp::cpp_int;

const int INF = 1e9;
const int MOD = 998244353;
const long long LINF = 4e18;

using ll = long long;
using vi = vector<int>;
using vl = vector<long long>;
using vs = vector<string>;
using vc = vector<char>;
using vb = vector<bool>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vvvvi = vector<vector<vector<vector<int>>>>;
using vvl = vector<vector<long long>>;
using vvvl = vector<vector<vector<long long>>>;
using vvvvl = vector<vector<vector<vector<long long>>>>;
using vvc = vector<vector<char>>;
using vvb = vector<vector<bool>>;
using vvvb = vector<vector<vector<bool>>>;
using vvvvb = vector<vector<vector<vector<bool>>>>;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define dump(x)  cout << #x << " = " << (x) << endl;
#define Yes(n) cout << ((n) ? "Yes" : "No"  ) << endl
#define ALL(obj) (obj).begin(),(obj).end()

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while(1){
        string s;
        cin >> s;
        if(s == "#") return 0;
        string t;
        cin >> t;
        ll ans = LINF;
        ll ins, era, swp, rot;
        cin >> ins >> era >> swp >> rot;
        rep(rot_cnt,s.size()){
            vvl dp(s.size() + 1, vl(t.size() + 1, LINF));
            dp[0][0] = rot_cnt * rot;
            rep(i,s.size() + 1)rep(j,t.size() + 1)if(dp[i][j] != LINF){
                if(i != s.size()){
                    if(rot_cnt >= s.size() - i) dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + era - rot);
                    else dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + era);
                }
                if(j != t.size()){
                    dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + ins);
                }
                if(i != s.size() && j != t.size()){
                    dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j] + swp);
                    if(s[i] == t[j]) dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j]);
                }
            }
            ans = min(ans, dp[s.size()][t.size()]);
            s.push_back(s[0]);
            s.erase(s.begin());
        }
        cout << ans << '\n';
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 5

code_snippet: #include <bits/extc++.h>

using ll = long long;

template <class T>
bool chmin(T& x, const T& v) {
  if (x > v) {
    x = v;
    return true;
  } else {
    return false;
  }
}

bool solve() {
  std::string X, Y;
  ll A, E, S, R;
  std::cin >> X;

  if (X == "#") {
    return false;
  }

  std::cin >> Y >> A >> E >> S >> R;

  ll INF = std::numeric_limits<ll>::max() / 2;

  ll ans = INF;

  int N = X.size();
  int M = Y.size();

  for (int r = 0; r < N; r++) {
    std::vector dp(N + 1, std::vector<ll>(M + 1, INF));

    dp[0][0] = R * r;

    for (int i = 0; i <= N; i++) {
      for (int k = 0; k <= M; k++) {
        if (i == N && k == M) continue;

        int idx = (i + r) % N;

        if (i < N) {
          chmin(dp[i + 1][k], dp[i][k] + E);
          if (idx < r) {
            chmin(dp[i + 1][k], dp[i][k] + E - R);
          }
        }

        if (k < M) {
          chmin(dp[i][k + 1], dp[i][k] + A);
        }

        if (i < N && k < M) {
          if (X[idx] == Y[k]) {
            chmin(dp[i + 1][k + 1], dp[i][k]);
          } else {
            chmin(dp[i + 1][k + 1], dp[i][k] + S);
          }
        }
      }
    }

    chmin(ans, dp[N][M]);
  }

  std::cout << ans << '\n';

  return true;
}

int main() {
  while (solve());
}
accuracy: 1
time_ms: 60
memory_kb: 3584
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

bool solve() {
    string X, Y;
    int A, E, S, R;
    cin >> X;
    if (X == "#") return false;
    cin >> Y >> A >> E >> S >> R;
    long long ans = 1LL << 60;
    int NX = X.size(), NY = Y.size();
    for (int r = 0; r < NX; r++) {
        vector<vector<long long>> dp(NX + 1,  vector<long long>(NY + 1, 1LL << 60));
        dp[0][0] = 0;
        for (int i = 0; i <= NX; i++) {
            for (int j = 0; j <= NY; j++) {
                if (i < NX) {
                    dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + E - (i < NX - r ? 0 : R));
                }
                if (j < NY) {
                    dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + A);
                }
                if (i < NX && j < NY) {
                    dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j] + (X[i] == Y[j] ? 0 : S));
                }
            }
        }
        ans = min(ans, dp[NX][NY] + (long long)r * R);
        X.push_back(X.front());
        X.erase(X.begin());
    }
    cout << ans << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

#include <atcoder/all>
using namespace atcoder;

using ll = long long;
using mint = modint998244353;

void chmin(ll &x, ll y) {
    if(x > y) x = y;
}

int f(char c, char d) {
    return (c != d);
}

bool solve() {
    string X;
    cin >> X;
    if(X == "#") return false;
    string Y;
    cin >> Y;
    ll A, E, S, R;
    cin >> A >> E >> S >> R;
    const int LX = X.size();
    const int LY = Y.size();
    const ll INF = 1LL << 60;
    ll ans = INF;
    for(int t = 0; t < LX; t++) {
        vector dp(LX + 1, vector<ll>(LY + 1, INF));
        dp[0][0] = 0;
        for(int i = 0; i <= LX; i++) {
            for(int j = 0; j <= LY; j++) {
                if(j + 1 <= LY) {
                    chmin(dp[i][j + 1], dp[i][j] + A);
                }
                if(i + 1 <= LX) {
                    chmin(dp[i + 1][j], dp[i][j] + (LX - i <= t ? E - R : E));
                }
                if(i + 1 <= LX && j + 1 <= LY) {
                    chmin(dp[i + 1][j + 1], dp[i][j] + S * f(X[i], Y[j]));
                }
            }
        }
        chmin(ans, dp[LX][LY] + R * t);
        rotate(X.begin(), X.begin() + 1, X.end());
        // cout << X << endl;
    }
    cout << ans << endl;
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 5

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T, typename S = T> S SUM(const vector<T> &a) {
    return accumulate(ALL(a), S(0));
}
template <typename S, typename T = S> S POW(S a, T b) {
    S ret = 1, base = a;
    for (;;) {
        if (b & 1)
            ret *= base;
        b >>= 1;
        if (b == 0)
            break;
        base *= base;
    }
    return ret;
}
template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define debug 1
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define debug 0
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 2 "library/Utility/random.hpp"

namespace Random {
mt19937_64 randgen(chrono::steady_clock::now().time_since_epoch().count());
using u64 = unsigned long long;
u64 get() {
    return randgen();
}
template <typename T> T get(T L) { // [0,L]
    return get() % (L + 1);
}
template <typename T> T get(T L, T R) { // [L,R]
    return get(R - L) + L;
}
double uniform() {
    return double(get(1000000000)) / 1000000000;
}
string str(int n) {
    string ret;
    rep(i, 0, n) ret += get('a', 'z');
    return ret;
}
template <typename Iter> void shuffle(Iter first, Iter last) {
    if (first == last)
        return;
    int len = 1;
    for (auto it = first + 1; it != last; it++) {
        len++;
        int j = get(0, len - 1);
        if (j != len - 1)
            iter_swap(it, first + j);
    }
}
template <typename T> vector<T> select(int n, T L, T R) { // [L,R]
    if (n * 2 >= R - L + 1) {
        vector<T> ret(R - L + 1);
        iota(ALL(ret), L);
        shuffle(ALL(ret));
        ret.resize(n);
        return ret;
    } else {
        unordered_set<T> used;
        vector<T> ret;
        while (SZ(used) < n) {
            T x = get(L, R);
            if (!used.count(x)) {
                used.insert(x);
                ret.push_back(x);
            }
        }
        return ret;
    }
}

void relabel(int n, vector<pair<int, int>> &es) {
    shuffle(ALL(es));
    vector<int> ord(n);
    iota(ALL(ord), 0);
    shuffle(ALL(ord));
    for (auto &[u, v] : es)
        u = ord[u], v = ord[v];
}
template <bool directed, bool multi, bool self>
vector<pair<int, int>> genGraph(int n, int m) {
    vector<pair<int, int>> cand, es;
    rep(u, 0, n) rep(v, 0, n) {
        if (!self and u == v)
            continue;
        if (!directed and u > v)
            continue;
        cand.push_back({u, v});
    }
    if (m == -1)
        m = get(SZ(cand));
    // chmin(m, SZ(cand));
    vector<int> ord;
    if (multi)
        rep(_, 0, m) ord.push_back(get(SZ(cand) - 1));
    else {
        ord = select(m, 0, SZ(cand) - 1);
    }
    for (auto &i : ord)
        es.push_back(cand[i]);
    relabel(n, es);
    return es;
}
vector<pair<int, int>> genTree(int n) {
    vector<pair<int, int>> es;
    rep(i, 1, n) es.push_back({get(i - 1), i});
    relabel(n, es);
    return es;
}
}; // namespace Random

/**
 * @brief Random
 */
#line 4 "sol.cpp"

int main() {
    for (;;) {
        string S, T;
        ll A, B, C, D;
        read(S);
        if (S == "#")
            break;
        read(T, A, B, C, D);

        ll ret = INF;
        rep(rot, 0, SZ(S)) {
            ll base = D * rot;

            vector dp(SZ(S) + 1, vector<ll>(SZ(T) + 1, INF));
            dp[0][0] = 0;
            rep(i, 0, SZ(S) + 1) rep(j, 0, SZ(T) + 1) {
                if (i < SZ(S) and j < SZ(T) and S[i] == T[j]) {
                    chmin(dp[i + 1][j + 1], dp[i][j]);
                }
                // add
                if (j < SZ(T))
                    chmin(dp[i][j + 1], dp[i][j] + A);
                // remove
                if (i < SZ(S)) {
                    if (i >= SZ(S) - rot)
                        chmin(dp[i + 1][j], dp[i][j] + B - D);
                    else
                        chmin(dp[i + 1][j], dp[i][j] + B);
                }
                // replace
                if (i < SZ(S) and j < SZ(T)) {
                    chmin(dp[i + 1][j + 1], dp[i][j] + C);
                }
            }
            chmin(ret, base + dp[SZ(S)][SZ(T)]);

            S.push_back(S.front());
            S.erase(S.begin());
        }
        print(ret);
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3840
final_rank: 13

code_snippet: #line 1 "D.cpp"
#include <vector>
#include <iostream>
#include <string>
#include <cassert>
using namespace std;
using ll = long long;
template<class T> inline bool chmax(T& a, const T& b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, const T& b) {if (b<a) {a=b; return true;} return false;}
constexpr int INTINF = 1000001000;
constexpr int INTMAX = 2147483647;
constexpr ll LLMAX = 9223372036854775807;
constexpr ll LLINF = 4450000000011100000;

#line 1 "/home/harui/CompetitiveProgramming/library/debug.hpp"



#ifdef LOCAL
#define dbg(x) std::cerr << __LINE__ << " : " << #x << " = " << (x) << std::endl
#else
#define dbg(x) true
#endif

#line 12 "/home/harui/CompetitiveProgramming/library/debug.hpp"
#include <utility>
#include <set>


template <typename T, typename U>
std::ostream& operator<<(std::ostream& os, const std::pair<T, U>& p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
  os << '[';
  for (int i=0; i<int(vec.size()); i++) {
    os << vec[i];
    if (i != int(vec.size())-1) os << ", ";
  }
  os << ']';
  return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::set<T>& st) {
  os << '{';
  auto itr = st.begin();
  while (itr != st.end()) {
    os << *itr;
    itr = next(itr);
    if (itr != st.end()) os << ", ";
  }
  os << '}';
  return os;
}



#line 15 "D.cpp"

void solve(string X, string Y) {
  ll A, E, S, R; cin >> A >> E >> S >> R;

  const int N = int(X.size());
  const int M = int(Y.size());

  ll ans = LLINF;


  // この辺になんかやる
  // 削除されるようなやつは,回転する意味なしｗ！ <- あとから回転の利点あり
  // ---
  // hoge; 
  // ---
  for(int rot=0; rot<N; rot++) {
    // X2 := X[rot, N) + X[0, rot)
    // A: arbitrary add
    // E: erase
    // S: replace
    // R: rotate

    // X2[i]を返す
    auto x2i = [&X, rot, N] (int i) -> char {
      assert(0 <= i && i < N);
      if (i < N-rot) return X[i+rot];
      else return X[i-(N-rot)];
    };

    ll cost = R * rot;
    vector<vector<ll>>dp(N+1, vector(M+1, LLINF));
    // dp[x][y] := X2の[0,i) で Yの[0,y)を作るための必要最低金額
    dp[0][0] = 0;
    for (int i=0;i<=N; i++) {
      for (int j=0; j<=M; j++) {
        //配列外参照に気をつける！！！！！
        // いま, X2[i]とY[j]に注目してる。

        // 普通にX2[i] == Y[j]の場合
        if (i < N && j < M && x2i(i) == Y[j]) chmin(dp[i+1][j+1], dp[i][j]);
        if (i <= N && j+1 <= M) chmin(dp[i][j+1], dp[i][j] + A); // 好きな文字挿入
        if (i < N && j < M) chmin(dp[i+1][j+1], dp[i][j] + S); // 置換

        //if (i+1<=N && j <= M) chmin(dp[i+1][j], dp[i][j] + E); // 削除. X2[i]を見てるわけだけど、"こいつが回転されている"⇔ iが[N-rot,N)の間にある
        if (i+1 <= N && j <= M) {
          if (N-rot <= i && i < N) chmin(dp[i+1][j], dp[i][j] + E - R);
          else chmin(dp[i+1][j], dp[i][j] + E);
        }


      }
    }
    dbg(rot);
    dbg(dp);
    chmin(ans, dp[N][M] + cost);
  }

  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

  while (true) {
    string X, Y; cin >> X;
    if (X == "#") break;
    cin >> Y;
    solve(X,Y);
  }
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3712
final_rank: 17

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <algorithm>
//#include <atcoder/all>
#include <bitset>
#include <cassert>
#include <cmath>
#include <deque>
#include <exception>
#include <fstream>
#include <iostream>
#include <map>
#include <mutex>
#include <queue>
#include <ratio>
#include <regex>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;
// using namespace atcoder;
// using mint = modint998244353;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
#define drep(i, n) for (int i = n - 1; i >= 0; i--)
#define srep(i, j, n) for (int i = j; i < n; i++)
#define sqrep(i, n) for (ll i = 1; i * i <= n; i++)
#define INF (int)(1e9 + 1e8)
#define LINF (ll)(1e18 + 1e17)
#define all(a) a.begin(), a.end()
#define eb emplace_back
#define mkp make_pair
#define mkt make_tuple
using ull = unsigned long long;
using vi = vector<int>;
using vd = vector<double>;
using vl = vector<ll>;
using vi2 = vector<vi>;
using vd2 = vector<vd>;
using vl2 = vector<vl>;
using vi3 = vector<vi2>;
using vl3 = vector<vl2>;
using vs = vector<string>;
using pi = pair<int, int>;
using tp = pair<int, pi>;
// using vm = vector<mint>;
// using vm2 = vector<vm>;
// using vm3 = vector<vm2>;

template <class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> inline void show_vector(vector<T>& a) {
    for (int i = 0; i < a.size(); i++) {
        cout << a[i] << " ";
    }
    cout << endl;
}

template <class T> inline void show_vector2(vector<vector<T>>& a) {
    for (int i = 0; i < a.size(); i++) {
        show_vector(a[i]);
    }
    cout << endl;
}

template <class T, class U> inline void show_map(map<T, U>& a) {
    for (pair<T, U> p : a) {
        cout << p.first << ": " << p.second << endl;
    }
}
template <class T, class U> inline void cerr_map(map<T, U>& a) {
    for (pair<T, U> p : a) {
        cerr << p.first << ": " << p.second << endl;
    }
}
template <class T, class U> inline void show_pair(pair<T, U>& a) {
    cout << a.first << " " << a.second << endl;
}
template <class T, class U> inline void cerr_pair(pair<T, U>& a) {
    cerr << a.first << " " << a.second << endl;
}
template <class T> inline void show_set(set<T>& a) {
    for (T i : a) {
        cout << i << " ";
    }
    cout << endl;
}
template <class T> inline void cerr_set(set<T>& a) {
    for (T i : a) {
        cerr << i << " ";
    }
    cerr << endl;
}

inline void yn(bool a) {
    if (a)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

ll ncr[100][100];

void calc_ncr() {
    ncr[0][0] = 1;
    for (int i = 0; i < 40 - 1; i++) {
        for (int j = 0; j <= i; j++) {
            ncr[i + 1][j] += ncr[i][j];
            ncr[i + 1][j + 1] += ncr[i][j];
        }
    }
}

// struct S {
//     mint a;
// };
// struct F {
//     int b;
// };
//  using S = int;
// S op(S a, S b) { return {a.a + b.a}; }
// S eee() { return {0}; }
// S mapping(F f, S x) { return {x.a + f.b}; }
// F composition(F f, F g) { return {f.b + g.b}; }
// F id() { return {0}; }
// using SEG = segtree<S, op, eee>;
//  using LAZY_SEG = lazy_segtree<S, op, eee, F, mapping, composition, id>;
void show_seg(int n) // SEG s, int n)
{
    rep(i, n) {
        // cout << s.get(i) << " ";
    }
    cout << endl;
}
struct UnionFind {
    vector<int> par;  // 親ノード
    vector<int> rank; // ランク

    UnionFind(int n = 1) { init(n); }

    void init(int n = 1) {
        par.resize(n);
        rank.resize(n);
        for (int i = 0; i < n; ++i)
            par[i] = i, rank[i] = 0;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        } else {
            int r = root(par[x]);
            return par[x] = r;
        }
    }

    bool issame(int x, int y) { return root(x) == root(y); }

    bool merge(int x, int y) {
        x = root(x);
        y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y);
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        return true;
    }
};

ll gcd_ext(ll a, ll b, ll& x, ll& y) {
    x = 1;
    ll x_next = 0;
    ll r = a;
    ll r_next = b;
    while (r_next != 0) {
        ll tmp = x_next;
        x_next = x - x_next * (r / r_next);
        x = tmp;

        tmp = r_next;
        r_next = r % r_next;
        r = tmp;
    }
    y = (r - a * x) / b;
    return r;
}
template <class T> inline void cerr_vector(vector<T>& a) {
    for (int i = 0; i < a.size(); i++) {
        cerr << a[i] << " ";
    }
    cerr << endl;
}

template <class T> inline void cerr_vector2(vector<vector<T>>& a) {
    for (int i = 0; i < a.size(); i++) {
        cerr_vector(a[i]);
    }
    cerr << endl;
}
int popcount(ull a) {
    int res = 0;
    while (a > 0) {
        if (a & 1) { res++; }
        a >>= 1;
    }
    return res;
}

ll pow_ll(ll b, ll k, ll g) {
    ll res = 1;
    ll tmp = b;
    while (k > 0) {
        if (k & 1) {
            /*
            if (k != 0 && res > __LONG_LONG_MAX__ / tmp)
            {
                return -1;
            }*/
            res *= tmp;

            res %= g;
        }
        k >>= 1;
        // todo: 消す
        /*
        if (k != 0 && tmp > __LONG_LONG_MAX__ / tmp)
        {
            return -1;
        }*/
        tmp *= tmp;

        tmp %= g;
    }
    return res;
}
using PQP = priority_queue<pair<ll, int>, vector<pair<ll, int>>,
                           greater<pair<ll, int>>>;
using P = pair<ll, ll>;
using vp = vector<P>;
using P3 = pair<ll, P>;
using vp3 = vector<P3>;
using P4 = pair<P3, int>;
using vp2 = vector<vp>;
using T = tuple<int, int, int, int>;
using t3 = tuple<ll, ll, ll>;
using vt = vector<T>;
vi dx = {0, 1, 0, -1, 1, 1, -1, -1};
vi dy = {1, 0, -1, 0, 1, -1, 1, -1};
constexpr ll M = 1000000007;
string x, y;
ll a, e, s, r;
ll dp[102][102];
void dpfunc(int r_cnt) {
    rep(i, 102) rep(j, 102) dp[i][j] = LINF;
    dp[0][0] = r_cnt * r;
    rep(i, x.size() + 1) {
        rep(j, y.size() + 1) {
            if (i < x.size() && j < y.size() && x[i] == y[j]) {
                chmin(dp[i + 1][j + 1], dp[i][j]);
            } else {
                chmin(dp[i + 1][j + 1], dp[i][j] + s);
            }
            if ((int)x.size() - i <= r_cnt) {
                chmin(dp[i + 1][j], dp[i][j] + e - r);
            } else {
                chmin(dp[i + 1][j], dp[i][j] + e);
            }
            chmin(dp[i][j + 1], dp[i][j] + a);
        }
    }
}
int main() {
    while (1) {
        cin >> x;
        if (x[0] == '#') { break; }
        cin >> y >> a >> e >> s >> r;

        ll ans = LINF;
        rep(i, x.size()) {

            dpfunc(i);
            x.push_back(x[0]);

            x.erase(x.begin());
            chmin(ans, dp[x.size()][y.size()]);
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3568
final_rank: 1

code_snippet: #include <algorithm>
#include <array>
#include <bit>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <ranges>
#include <regex>
#include <set>
#include <span>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// #include <atcoder/dsu>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(a) a.begin(), a.end()
using namespace std;

template <class T>
inline bool chmin(T &a, T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

template <class T1, class T2>
std::ostream &operator<<(std::ostream &out, const pair<T1, T2> &A) {
	cout << "{" << A.first << "," << A.second << "}";
	return out;
}

template <class T1, class T2>
std::ostream &operator<<(std::ostream &out, const map<T1, T2> &M) {
	for (const auto &A : M) {
		cout << "{" << A.first << "," << A.second << "}";
	}
	return out;
}

template <class T1>
std::ostream &operator<<(std::ostream &out, const set<T1> &M) {
	cout << "{";
	for (const auto &A : M) {
		cout << A << ", ";
	}
	cout << "}" << endl;
	return out;
}

template <class T1>
std::ostream &operator<<(std::ostream &out, const multiset<T1> &M) {
	cout << "{";
	for (const auto &A : M) {
		cout << A << ", ";
	}
	cout << "}" << endl;
	return out;
}

template <class T>
std::ostream &operator<<(std::ostream &out, const vector<T> &A) {
	for (const T &a : A) {
		cout << a << " ";
	}
	return out;
}

void print() { cout << endl; }

template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	cout << H << " ";
	print(T...);
}

template <class T>
std::istream &operator>>(std::istream &in, vector<T> &A) {
	for (T &a : A) {
		std::cin >> a;
	}
	return in;
}

using ll = long long;
// using mint = modint1000000007;
// using PII = pair<int, int>;
// using PLL = pair<ll, ll>;
// using Graph = vector<vector<int>>;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr ll LINF = numeric_limits<ll>::max() / 2;

// ランレングス圧縮
// イテレータを受け取る
// verify: https://atcoder.jp/contests/abc380/submissions/60002447
template <typename T, typename Iterator>
vector<pair<T, int>> RLE(Iterator begin, Iterator end) {
	vector<pair<T, int>> res;
	for (auto itr = begin; itr != end; ++itr) {
		if (res.empty() || res.back().first != *itr) {
			res.emplace_back(*itr, 1);
		} else {
			res.back().second++;
		}
	}
	return res;
}

// 座標圧縮
// unordered_mapが使えない場合はmapに変更しよう
// https://atcoder.jp/contests/abc213/submissions/60002695
template <typename T>
unordered_map<T, int> compress(vector<T> &X) {
	auto tmp = X;
	ranges::sort(tmp);
	tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
	unordered_map<T, int> res;
	for (int i = 0; i < (int)tmp.size(); i++) {
		res[tmp[i]] = i;
	}
	return res;
}

ll edit_dis(string X, string Y, ll A, ll E, ll S, ll R, int rotate_num) {
	int N = X.size();
	int M = Y.size();
	vector dp(N + 1, vector<ll>(M + 1, LINF));
	dp[0][0] = 0;
	for (int i = 0; i <= N; i++) {
		for (int j = 0; j <= M; j++) {
			// i+1,j+1に遷移
			if (i < N && j < M) {
				if (X[i] == Y[j])
					chmin(dp[i + 1][j + 1], dp[i][j]);
				else
					chmin(dp[i + 1][j + 1], dp[i][j] + S);
			}
			// i+1, jに遷移
			if (i < N) {
				if (i < N - rotate_num) {
					chmin(dp[i + 1][j], dp[i][j] + E);
				} else {
					chmin(dp[i + 1][j], dp[i][j] + E - R);
				}
			}
			// i, j+1に遷移
			if (j < M) {
				chmin(dp[i][j + 1], dp[i][j] + A);
			}
		}
	}
	return dp[N][M];
}

bool solve() {
	// ここからスタート
	string X, Y;
	cin >> X >> Y;
	if (X == "#") return false;
	ll A, E, S, R;
	cin >> A >> E >> S >> R;
	int N = X.size();
	ll ans = LINF;
	rep(i, N) {
		// i回rotate
		ll cost = edit_dis(X, Y, A, E, S, R, i);
		chmin(ans, cost + ll(i) * R);
		if (N >= 1) X = X.substr(1, N - 1) + X.substr(0, 1);
	}
	cout << ans << endl;
	return true;
}

int main(void) {
	std::cin.tie(0)->sync_with_stdio(0);
	while (solve());
}
accuracy: 1
time_ms: 60
memory_kb: 3712
final_rank: 17

code_snippet: #include<bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;

#define all(v) v.begin(),v.end()
using ll = long long;
using ull = unsigned long long;
using lll = __int128;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using vp=vector<pair<ll, ll>>;
//using mint=modint1000000007;
//using mint=modint998244353;

const ll INF=1ll<<60;
ll mod10=1e9+7;
ll mod99=998244353;
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<n;++i)
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

bool solve(){
	string X,Y;cin>>X;if(X=="#") return 1;cin>>Y;
	ll a,e,s,r;cin>>a>>e>>s>>r;
	ll N=X.size(),M=Y.size();
	ll ans=INF;
	rep(w,N){
		vvll dp(N+1,vll(M+1,INF));
		dp[0][0]=0;
		rep(i,N+1) rep(j,M+1){
			if(j<M) chmin(dp[i][j+1],dp[i][j]+a);
			if(i<N) chmin(dp[i+1][j],dp[i][j]+(i<N-w?e:e-r));
			if(i<N&&j<M) chmin(dp[i+1][j+1],dp[i][j]+(X[i]==Y[j]?0:s));
		}
		chmin(ans,dp[N][M]+w*r);
		X=X.substr(1)+X[0];
	}
	cout << ans << endl;
	return 0;
}



int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	ll T=1;//cin>>T;
	while(!solve());
}
accuracy: 1
time_ms: 50
memory_kb: 3624
final_rank: 12

code_snippet: # include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
const double pi = acos(-1);
template<class T>constexpr T inf() { return ::std::numeric_limits<T>::max(); }
template<class T>constexpr T hinf() { return inf<T>() / 2; }
template <typename T_char>T_char TL(T_char cX) { return tolower(cX); }
template <typename T_char>T_char TU(T_char cX) { return toupper(cX); }
template<class T> bool chmin(T& a,T b) { if(a > b){a = b; return true;} return false; }
template<class T> bool chmax(T& a,T b) { if(a < b){a = b; return true;} return false; }
int popcnt(unsigned long long n) { int cnt = 0; for (int i = 0; i < 64; i++)if ((n >> i) & 1)cnt++; return cnt; }
int d_sum(ll n) { int ret = 0; while (n > 0) { ret += n % 10; n /= 10; }return ret; }
int d_cnt(ll n) { int ret = 0; while (n > 0) { ret++; n /= 10; }return ret; }
ll gcd(ll a, ll b) { if (b == 0)return a; return gcd(b, a%b); };
ll lcm(ll a, ll b) { ll g = gcd(a, b); return a / g*b; };
ll MOD(ll x, ll m){return (x%m+m)%m; }
ll FLOOR(ll x, ll m) {ll r = (x%m+m)%m; return (x-r)/m; }
template<class T> using dijk = priority_queue<T, vector<T>, greater<T>>;
# define all(qpqpq)           (qpqpq).begin(),(qpqpq).end()
# define UNIQUE(wpwpw)        (wpwpw).erase(unique(all((wpwpw))),(wpwpw).end())
# define LOWER(epepe)         transform(all((epepe)),(epepe).begin(),TL<char>)
# define UPPER(rprpr)         transform(all((rprpr)),(rprpr).begin(),TU<char>)
# define rep(i,upupu)         for(ll i = 0, i##_len = (upupu);(i) < (i##_len);(i)++)
# define reps(i,opopo)        for(ll i = 1, i##_len = (opopo);(i) <= (i##_len);(i)++)
# define len(x)                ((ll)(x).size())
# define bit(n)               (1LL << (n))
# define pb push_back
# define eb emplace_back
# define exists(c, e)         ((c).find(e) != (c).end())

struct INIT{
	INIT(){
		std::ios::sync_with_stdio(false);
		std::cin.tie(0);
		cout << fixed << setprecision(20);
	}
}INIT;

namespace mmrz {
	void solve();
}

int main(){
	mmrz::solve();
}
#define debug(...) (static_cast<void>(0))

using namespace mmrz;

using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using ull = unsigned long long;
using lll = __int128;
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

// [BEGIN] template の include

int SOLVE(){
	string s, t;
	cin >> s;
	if(s == "#")return 1;
	cin >> t;

	ll A, E, S, R;
	cin >> A >> E >> S >> R;

	ll ans = hinf<ll>();

	int n = len(s), m = len(t);

	rep(_, n){
		ll base = _*R;
		vector dp(n+1, vector(m+1, hinf<ll>()));
		dp[0][0] = 0;

		rep(i, n+1)rep(j, m+1){
			if(j != m)chmin(dp[i][j+1], dp[i][j]+A);
			if(i != n){
				chmin(dp[i+1][j], dp[i][j]+(i<n-_?E:E-R));
			}				
			if(i != n && j != m)chmin(dp[i+1][j+1], dp[i][j]+(s[i] == t[j] ? 0 : S));
		}
		chmin(ans, base+dp[n][m]);
		s = s.substr(1)+s[0];
	}

	cout << ans << '\n';

	return 0;
}

void mmrz::solve(){
	while(!SOLVE());
}
accuracy: 1
time_ms: 40
memory_kb: 3840
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) (a).begin(), (a).end()
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rrep(i, n) for (int i = (int)(n) - 1; 0 <= i; --i)
template <typename T> bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
void solve();
string X,Y;
int A,E,S,R;
signed main(){
  cin.tie(nullptr)->sync_with_stdio(false);
  cout << fixed << setprecision(20);
  int TESTCASES = 1<<30;
  //cin >> TESTCASES;
  while (TESTCASES--) {
    cin>>X;
    if(X=="#")break;
    cin>>Y>>A>>E>>S>>R;
    solve();
  }
}
void solve() {
  int n=X.size(),m=Y.size();
  ll ans=(ll)1<<60;
  rep(shift,n){
    vector dp(n+1,vector<ll>(m+1,(ll)1<<60));
    dp[0][0]=0;
    for(int i=0;i<=n;++i)for(int j=0;j<=m;++j){
      if(i<n&&j<m){
        ll cost=0;
        if(X[i]!=Y[j])cost+=S;
        if(n-shift<=i)cost+=R;
        chmin(dp[i+1][j+1],dp[i][j]+cost);
      }
      if(i<n)chmin(dp[i+1][j],dp[i][j]+E);
      if(j<m)chmin(dp[i][j+1],dp[i][j]+A);
    }
    chmin(ans,dp[n][m]);
    X=X.substr(1,n-1)+X.substr(0,1);
  }
  cout<<ans<<'\n';
}
accuracy: 1
time_ms: 40
memory_kb: 3712
final_rank: 5

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<long long>
#define vvl vector<vector<long long>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define YES cout<<"Yes"<<endl;return 0;
#define NO cout<<"No"<<endl;return 0;
#define inf 4000000000000000000LL
#define mod 998244353LL
//#define mod 1000000007LL
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード


//#include<boost/multiprecision/cpp_int.hpp>
//#define bbi boost::multiprecision::cpp_int

//#include<atcoder/lazysegtree>

//√の値が整数かを調べる
bool isSqrt(ll n) {
	if (n < 0) return false;
	ll sqrtN = static_cast<ll>(sqrt(n));
	return sqrtN * sqrtN == n;
}

//整数同士の累乗の計算をする。
ll power(ll A, ll B) {
	ll result = 1;
	for (ll i=0;i<B;i++){
		result *= A;
	}
	return result;
}

//素因数分解
vector<ll> makePrime(ll n){
	vector<ll> factors;
	while (n % 2 == 0) {
		factors.push_back(2);
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors.push_back(i);
			n /= i;
		}
	}
	if (n > 2) {
		factors.push_back(n);
	}
	return factors;
}

//map形式で、nを素因数分解した値を返す
map<ll,ll> makeMapPrime(ll n){
	map<ll,ll> factors;
	while (n % 2 == 0) {
		factors[2]++;
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors[i]++;
			n /= i;
		}
	}
	if (n > 2) {
		factors[n]++;
	}
	return factors;
}

// nのk乗をmodで割った余りを計算
ll power_mod(ll n, ll k){
	long long result = 1;
	while (k > 0){
		if ((k&1) ==1)result=(result*n)%mod;
		n=n*n%mod;
		k >>= 1;
	}
	return result;
}

//mod mにおけるaの逆元を計算
ll modinv(ll a, ll m) {
	ll b = m, u = 1, v = 0;
	while (b) {
		ll t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m; 
	if (u < 0) u += m;
	return u;
}

//場合の数 nCr を求める
ll ncr(ll n,ll r) {
	if(n<r)return 0;
	vvl dp(n+1,vl(r+1));
	rep (i,n+1)dp[i][0] = 1;
	rep (i,r+1)dp[i][i] = 1;
	loop (i,1,n){
		loop (j,1,min((ll)i-1,r)) {
			//nCr= n-1Cr-1 + n-1Cr
			dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
		}
	}
	return dp[n][r];
}

//受け取った文字列を、第2引数が0なら全て小文字に、1なら大文字に変換する関数
string cnvString(const string &str, int mode) {
	string result = str;
	if (mode == 0) {
		// 小文字に変換
		for (char &c : result) {
			c = tolower(c);
		}
	} else if (mode == 1) {
		// 大文字に変換
		for (char &c : result) {
			c = toupper(c);
		}
	}
	return result;
}

//第一引数で受け取った数を、第二引数で受け取った数の進数と見做して、第三引数の進数へ変換する。
string cnvBase(const string &str, ll from_base, ll to_base) {
	ll num = 0;
	//小文字があったら大文字に変換
	string num_str=cnvString(str,1);
	// 数値を10進数に変換
	for (char digit : num_str) {
		num = num * from_base + (isdigit(digit) ? digit - '0' : digit - 'A' + 10);
	}
	string result;
	// 数値を目的の基数に変換
	while (num > 0) {
		ll remainder = num % to_base;
		result.push_back(remainder < 10 ? remainder + '0' : remainder - 10 + 'A');
		num /= to_base;
	}
	// 結果を逆順にして返す
	reverse(result.begin(), result.end());
	return result.empty() ? "0" : result;
}

//底がaの対数xを計算。ただし小数点は繰り上げ。
ll logax(ll a, ll x){
	if(x<=1)return 0;
	ll result = 1;
	ll power = 1;
	while (power < (x+a-1) / a){
		power *= a;
		result++;
	}
	return result;
}

//第一引数を第二引数で割った余りを計算、割る数はint範囲
ll bigmd(const string &num, int md) {
	ll ans = 0;
	ll SIZ = 9; //9桁のチャンク
	ll base = 1000000000;//SIZ個の0
	rep(i,(num.size()-1)/SIZ+1){
		ll chunk = 0;
		ll l = i*SIZ;
		ll r = min((ll)num.size(),l+SIZ);
		if(r!=num.size()){
			ans = (ans*base+stoll(num.substr(l,r-l)))%md;
		}else{
			rep(i,r-l)ans*=10;
			ans=(ans+stoll(num.substr(l,r-l)))%md;
		}
	}
	return ans;
}

//受け取った2次元文字の外側に、文字pをコーティングする。
vector<string> pad(vector<string> &s,char p){
	ll h=s.size();
	ll w=s[0].size();
	vector<string> res(h+2,string(w+2,p));
	rep(i,h)rep(j,w)res[i+1][j+1]=s[i][j];
	return res;
}

//ax+by=cの整数解を得る ただし、cはgcd(a,b)の倍数でない場合、0,0になる
pair<ll,ll> ex_euclid(ll a,ll b,ll c){
	if(a<0||b<0||c<0){
		pair<ll,ll>ans=ex_euclid(abs(a),abs(b),abs(c));
		if(a<0)ans.first*=-1;
		if(b<0)ans.second*=-1;
		if(c<0)ans.first*=-1,ans.second*=-1;
		return ans;
	}
	if(c!=1){
		ll d=gcd(a,b);
		if(c%d!=0)return make_pair(0,0);
		pair<ll,ll>ans = ex_euclid(a/d,b/d,1);
		ans.first*=c/d;
		ans.second*=c/d;
		return ans;
	}
	if(a<b){
		pair<ll,ll>ans=ex_euclid(b,a,c);
		swap(ans.first,ans.second);
		return ans;
	}
	if(a==1&&b==0)return make_pair(1,0);
	else if(b==0) return make_pair(0,0);
	ll x,y;
	tie(x,y)=ex_euclid(b,a%b,c);
	pair<ll,ll> ans=make_pair(y,x-(a/b)*y);
	return ans;
}

//オイラーのトーシェント関数。N以下のNと互いに素な物の数を返す。
ll euler(ll n){
	unordered_map<ll,ll> factors;
	ll tmp=n;
	while (tmp % 2 == 0) {
		factors[2]++;
		tmp /= 2;
	}
	for (ll i=3; i*i<=tmp;i+=2) {
		while (tmp%i == 0) {
			factors[i]++;
			tmp/= i;
		}
	}
	if (tmp > 2)factors[tmp]++;
	ll ans=1;
	for(const auto & val:factors){
		ans*=power(val.first,val.second-1)*(val.first-1);
	}
	return ans;
}

// Union-Find
struct UnionFind {
	vector<int> par, siz;
	UnionFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return par[x] = root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	// x を含むグループと y を含むグループとを併合する
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if (x == y) return false;
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	// x を含むグループのサイズ
	int size(int x) {
		return siz[root(x)];
	}
};

//重み付きUF
struct PotentialUnionFind {
	ll n;
	vl par, siz, pot;
	PotentialUnionFind(ll N) : par(N,-1) , siz(N,1) , pot(N,0){n=N;}
	// 根を求める
	ll root(ll x) {
		if (par[x] == -1) return x;
		ll tmp = root(par[x]);
		pot[x] += pot[par[x]];
		par[x] = tmp;
		return par[x];
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(ll x, ll y) {
		return root(x) == root(y);
	}
	//x よりいくつ大きい所に y があるか。根が一致しない場合は"0"
	ll potential(ll x,ll y){
		if(root(x) != root(y)) return 0;
		else return pot[y]-pot[x];
	}
	//x より w だけ大きい状態として y を併合。
	bool unite(ll x, ll y, ll w) {
		ll rx = root(x),ry = root(y);
		if (rx == ry) return false;
		w += pot[x]-pot[y];
		if (siz[rx] < siz[ry]) swap(rx, ry),w*=-1;
		par[ry] = rx;
		siz[rx] += siz[ry];
		siz[ry] = 0;
		pot[ry] = w;
		return true;
	}
	// x を含むグループのサイズ
	ll size(ll x) {
		return siz[root(x)];
	}
	//小さい順にUnionFindグラフを調整、O(n log n)
	void regulation(){
		vvl r(n);
		rep(i,n)r[root(i)].push_back(i);
		rep(i,n){
			if(r[i].size()==0)continue;
			ll mn = i;
			rep(j,r[i].size())if(pot[mn]>pot[r[i][j]])mn=r[i][j];
			siz[mn]=siz[i];
			siz[i]=0;
			ll tmp = pot[mn];
			rep(j,r[i].size()){
				pot[r[i][j]]-=tmp;
				par[r[i][j]] = mn;
			}
			par[mn]=-1;
		}
	}
	void debug(){
		rep(i,n)cout<<setw(4)<<left<<par[i]<<" ";
		cout<<endl;
		rep(i,n)cout<<setw(4)<<left<<pot[i]<<" ";
		cout<<endl;
	}
};

//分離可能UnionFind、経路圧縮をしない。
struct CuttingFind{
	vector<int> par, siz;
	CuttingFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	//根x と 根y のグループを併合する(お互い根ではない時、falseで何もしない)
	bool unite(int x, int y) {
		if (issame(x,y) || par[x] != -1 || par[y] != -1) {
			cout<<"error"<<endl;
			return false;
		}
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	//根の側から、その直系の子供を分離する。片方が根でもう片方が直系の子でなければならない。
	bool separate(int x,int y){
		if(par[y]==-1)swap(x,y);
		if(par[y]!=x||par[x]!=-1){
			cout<<"error2"<<endl;
			return false;
		}
		siz[x] -= siz[y];
		par[y]=-1;
		return true;
	}
	// x を含むグループのサイズを求める
	int size(int x) {
		return siz[root(x)];
	}
};
//セグ木,乗せる値の型が必要
template<typename T>
struct SegTree{
	ll size;
	ll tall;
	vector<T> data;
	function<T(T,T)> p;
	//セグ木に乗せる値の初期値をa配列にし、putの関数をセグ木に乗せる、dをデフォルト値に。
	SegTree(vector<T> a,function<T(T,T)> put,T d) : data(power(2,logax(2,a.size())+1)) {
		size = data.size()/2;
		tall=logax(2,size)+1;
		p=put;
		ll tmp=size;
		data = vector<T>(size*2,d);
		while(tmp!=0){
			if(tmp==size)rep(i,a.size())data[tmp+i]=a[i];
			else rep(i,tmp) data[tmp+i]=p(data[2*(tmp+i)],data[2*(tmp+i)+1]);
			tmp/=2;
		}
	}
	//更新、t番目の値をxにする。
	void update(ll t,T x){
		t+=size;
		while(t!=0){
			if(t>=size)data[t]=x;
			else data[t]=p(data[2*t],data[2*t+1]);
			t/=2;
		}
	}
	//取得、l~r区間内の評価値を取得する。
	T get(ll l,ll r){
		//lとrが範囲外なら範囲内に正す
		l=max(0LL,l);
		r=min(r,size-1);
		r++;
		T ans=data[0];
		ll pos=l+size;
		ll wid=1;
		//出来る限り上に上げきる。
		while(l+(wid*2)<=r){
			while(l%(wid*2)==0&&l+(wid*2)<=r)pos/=2,wid*=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		//上げ終わったので今度は下げる
		while(l!=r){
			while(l+wid>r)pos*=2,wid/=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		return ans;
	}
	//セグ木デバッグ用、丸ごと出力
	void print(){
		rep(i,size)cout<<setw(7)<<left<<i;
		cout<<endl;
		ll pos=size;
		rep(i,tall){
			rep(j,size){
				if(j%power(2,i)==0)cout<<setw(7)<<left<<data[pos],pos++;
				else cout<<"       ";
			}
			pos/=4;
			cout<<endl;
		}
	}
};

//グリッド問題等用
vl dx={1,0,-1,0};
vl dy={0,1,0,-1};

ll solve(){
	string x,y;
	cin>>x;
	if(x=="#"){
		return 1;
	}
	cin>>y;
	ll a,e,s,r;
	cin>>a>>e>>s>>r;
	s=min(s,a+e);
	r=min(r,a+e);

	ll ans=inf;
	rep(k,x.size()){
		string xd;
		rep(j,x.size()){
			xd.push_back(x[(j+k)%x.size()]);
		}
		vvl dp(x.size()+1,vl(y.size()+1,inf));
		dp[0][0]=k*r;
		rep(i,x.size()+1){
			rep(j,y.size()+1){
				//変更/同じの遷移
				if(i!=x.size()&&j!=y.size()){
					if(xd[i]==y[j])dp[i+1][j+1]=min(dp[i][j],dp[i+1][j+1]);
					else dp[i+1][j+1]=min(dp[i][j]+s,dp[i+1][j+1]);
				}
				//追加の遷移
				if(j!=y.size()){
					dp[i][j+1]=min(dp[i][j]+a,dp[i][j+1]);
				}
				//削除の遷移
				if(i!=x.size()){
					if(i+k>=x.size())dp[i+1][j]=min(dp[i][j]+e-r,dp[i+1][j]);
					else dp[i+1][j]=min(dp[i][j]+e,dp[i+1][j]);
				}
			}
		}
		//デバッグ
		//cout<<xd<<endl;
		//if(ans>dp[x.size()][y.size()])cout<<k<<endl;
		ans=min(ans,dp[x.size()][y.size()]);
		
	}
	cout<<ans<<endl;
	return 0;
}

//メイン
int main(){
	while(solve()==0);
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3584
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(a) a.begin(),a.end()
#define reps(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) reps(i, 0, n)
#define rreps(i, a, n) for (int i = (a); i > (int)(n); i--)
const long long mod = 1000000007;
const long long INF = 1e18;
ll myceil(ll a, ll b) {return (a+b-1)/b;}


string s,t;

void solve() {
	int x,y;
	x = s.length();
	y = t.length();

	int a,e,w,r;
	cin >> a >> e >> w >> r;


	vector<vector<vector<int>>> dp(103,vector<vector<int>> (103,vector<int> (103,1e9+100)));

	rep(_,x+2) {
		dp[_][0][0] = _*r;
		rep(i,x+1) {
			rep(j,y+1) {
				if (s[i] == t[j]) {
					dp[_][i+1][j+1] = min(dp[_][i+1][j+1],dp[_][i][j]);
				}
				if (x-i > _) {
					dp[_][i+1][j] = min(dp[_][i+1][j],dp[_][i][j]+e);
				}
				else {
					dp[_][i+1][j] = min(dp[_][i+1][j],dp[_][i][j]+e-r);
				}
				dp[_][i][j+1] = min(dp[_][i][j+1],dp[_][i][j]+a);
				dp[_][i+1][j+1] = min(dp[_][i+1][j+1],dp[_][i][j]+w);
			}
		}
		s = s.substr(1)+s[0];
	}

	int ans = 1e9;
	rep(i,x) {
		ans = min(ans,dp[i][x][y]);
	}
	cout << ans << endl;
	return;
}


int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
	while (cin >> s >> t && s != "#") {
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 7944
final_rank: 20

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

string X;

void solve(){
    int N = len(X);
    string Y; cin >> Y;
    int M = len(Y);
    ll a, e, s, r; cin >> a >> e >> s >> r;
    ll ans = INF;
    rep(rot, N + 1){
        vvl dp(N + 1, vl(M + 1, INF));
        dp[0][0] = rot * r;
        rep(i, N + 1) rep(j, M + 1){
            if (i < N && j < M) dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j] + (X[i] != Y[j]) * s);
            if (j < M) dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + a);
            if (i < N) dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + e - (i >= N - rot ? r : 0));
        }
        ans = min(ans, dp[N][M]);
        rotate(X.begin(), X.begin() + 1, X.end());
    }
    cout << ans << endl;
}
int main(){
    while (true){
        cin >> X;
        if (X == "#") break;
        solve();
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3524
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(),x.end()
#define dbg(x) cerr << #x << ':' << (x) << endl;
using ll = long long;
using ld = long double;

void solve() {
    string X,Y;
    cin >> X;
    if (X == "#") exit(0);
    cin >> Y;
    ll A,E,S,R;
    cin >> A >> E >> S >> R;

    // 回転後の文字列Xrと回転した回数rでの最適解を求める
    auto func = [&](string& XR, int r)->ll{
        vector<vector<ll>> dp(XR.size()+1, vector<ll>(Y.size()+1, INT_MAX));
        dp[0][0] = r*R;
        for (int i = 0; i <= XR.size(); ++i) {
            for (int j = 0; j <= Y.size(); ++j) {
                // 編集 or コスト無
                if (i < XR.size() && j < Y.size()) {
                    if (XR[i] == Y[j]) dp[i+1][j+1] = min(dp[i+1][j+1],dp[i][j]);
                    else dp[i+1][j+1] = min(dp[i+1][j+1], dp[i][j] + S);
                }
                // 削除
                if (i < XR.size()) {
                    // 回転のコストも消す場合
                    if (i >= XR.size()-r) dp[i+1][j] = min(dp[i+1][j], dp[i][j] + E - R);
                    else dp[i+1][j] = min(dp[i+1][j], dp[i][j] + E);
                }
                // 追加
                if (j < Y.size()) {
                    dp[i][j+1] = min(dp[i][j+1], dp[i][j] + A);
                }
            }
        }

        return dp[XR.size()][Y.size()];
    };

    string Xr = X;
    ll ans = LLONG_MAX;
    for (int i = 0; i < X.size(); ++i) {
        ans = min(ans, func(Xr,i));
        
        // 先頭の文字列を後ろに追加
        reverse(ALL(Xr));
        char tmp = Xr.back();
        Xr.pop_back();
        reverse(ALL(Xr));
        Xr.push_back(tmp);
    }

    cout << ans << endl;
}

int main()
{   
    while (true) solve();
}
accuracy: 1
time_ms: 60
memory_kb: 3400
final_rank: 14

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    using P=pair<ll,ll>;
    using tp=tuple<ll,ll,ll>;
    const int INF=1001001001;
    const ll INFL=1e18;
    const int mod=998244353;


    bool solve(){
		string s;
		cin>>s;
		if(s=="#")return false;
		string t;
		cin>>t;
		int a,b,c,d;
		cin>>a>>b>>c>>d;
		int S=s.size(),T=t.size();
		int ans=INF;
		rep(rot,S){
			vector<vector<int>>dp(S+2,vector<int>(T+2,INF));
			dp[0][0]=rot*d;
			rep(i,S+1){
				rep(j,T+1){
					if(i<S&&j<T&&s[i]==t[j]){chmin(dp[i+1][j+1],dp[i][j]);}
					chmin(dp[i][j+1],dp[i][j]+a);
					chmin(dp[i+1][j],dp[i][j]+(i<S-rot?b:b-d));
					chmin(dp[i+1][j+1],dp[i][j]+c);
				}
			}
			chmin(ans,dp[S][T]);
			for(int k=0;k+1<S;k++){swap(s[k],s[k+1]);}
		}
		cout<<ans<<endl;
		return true;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);

		while(1){
			if(!solve())return false;
		}
		
        return 0;
    }
accuracy: 1
time_ms: 40
memory_kb: 3584
final_rank: 2