Sie sind auf Seite 1von 6

#include <iostream>

#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string>
#include <vector>
#include <math.h>
#include <cmath>
#include <map>
#include <sstream>
#include <numeric>
#include <bitset>
#include <stack>
#include <limits>
#include <iomanip>
#include <math.h>
#include <string.h>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef pair<ll,ll> pll;
typedef vector< pair<int,int> > vii;
#define debug(x) cout << #x << " = " << x << endl
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,i) for(typeof((c).begin()) i = (c).begin(); i !=
(c).end(); i++)
#define For(i,a,b) for(int i=a;i<=b;i++)
#define present(c,x) ((c).find(x) != (c).end())
// for
set/map
#define cpresent(c,x) (find(all(c),x) != (c).end()) //for
vector
double EPS = 1e-9;
#define MOD 1000000007
//setbase - cout << setbase (16); cout << 100 << endl; Prints
64
//setfill cout << setfill ('x') << setw (5); cout << 77 <<
endl; prints xxx77

//setprecision - cout << setprecision (4) << f << endl; Prints


x.xxxx
const ll INF = 1000000001;
// base and base_digits must be consistent // 65-90 A -Z _ is
95
// 97 - 122 a -z 48 -57 0-9
#define dsf(a) int a;scanf("%d",&a)
#define sf(a) scanf("%d",&a)
#define sfl(a) scanf("%lld",&a)
int g_k;
int max_n = 0;
struct node
{
node(){idx = vi(g_k);cost = 0;}
vi idx; ll cost; ll parent;
};
bool operator < (const node&a,const node&b) {
return a.cost > b.cost;
}
ll conv_hash(vi v)
{
// convert vector<int> to hash
ll val = 0;
ll mult = 1;
For(i, 0, sz(v) - 1)
{
val += v[i]*mult;
mult *= max_n;
}
return val;
}
vi hash_to_ve(ll idx)
{
vi ret(g_k);
For(i, 0, g_k -1)
{
ret[i] = (idx % max_n);
idx = idx / max_n;
}
return ret;
}
map<ll, ll> parent;
vector<vi> g_next;

vvi mc;
int g_cc,g_sv;
vs xi;
map <char,int> vocab_inv;
int cost(string state)
{
size_t n = state.length();
int cost = 0;
For(i, 0, n-1)
For(j, i+1, n-1)
{
cost += mc[vocab_inv[state[i]]][vocab_inv[state[j]]];
}
return cost;
}
vi sub(vi a, vi b) // b - a
{
vi ret(sz(b));
For(i, 0, sz(b)-1)
ret[i] = b[i] - a[i];
return ret;
}
// xi k x n
// - is sv
int h2(int r1, int r2, int c1, int c2)
{
size_t l1 = xi[r1].size();
size_t l2 = xi[r2].size();
l1 -= c1;
l2 -= c2;
vvi dp(l1+1,vi(l2+1,INF));
dp[0][0] = mc[g_sv][vocab_inv[xi[r2][j]]];
For(i,1,l2) dp[0][i]=0;
For(j,1,l1) dp[j][0]=0;
For(i,1,l2) For(j,0,i-1) dp[0][i] += g_cc + mc[g_sv]
[vocab_inv[xi[r2][j]]];
For(j,1,l1) For(i,0,j-1) dp[j][0] += g_cc +
mc[vocab_inv[xi[r1][i]]][g_sv];
for (int i = 1; i <= l1; i ++) {
for (int j =1; j <= l2; j++) {
dp[i][j] = min(dp[i][j],min(dp[i-1]
[j-1]+mc[vocab_inv[xi[r1][i]]][vocab_inv[xi[r2][j]]],

min(dp[i-1][j]+mc[vocab_inv[xi[r1][i]]][g_sv]+g_cc,g_cc+dp[i]
[j-1]+mc[g_sv][vocab_inv[xi[r2][j]]])));
}
}
return dp[l1-1][l2-1];
}
int h()
{
return 0;
}
int main()
{
// input
double t; cin>>t;string tmp;
dsf(sv);g_sv = sv;getline(cin,tmp);string
inp;getline(cin,inp);string vocab;
int i =0;
while(i < inp.length())
{
vocab = vocab + inp[i];
i += 3;
}
mc = vvi(sv + 1,vi(sv + 1));
vocab = vocab + '-';
For(i,0,sv) vocab_inv[vocab[i]] = i;
dsf(k);xi = vs(k); g_k = k;
For(i, 0, k-1){ cin>>xi[i]; max_n = max(max_n,sz(xi[i]));}
max_n += 1;
dsf(cc); g_cc = cc;
For(i, 0, sv) For(j, 0, sv) sf(mc[i][j]);
g_next = vvi((1<<k) - 1,vi(k));
char hash;cin>>hash;
// input ends
For(i, 1, (1<<k) - 1) // i is the number of 1s
{
int orig = i;
For(j,1,k)
{
g_next[orig-1][j-1] = (i%2);
i = i/2;
}
i = orig;
}

//search
node start,end;
start.cost = 0; start.parent = -1;
priority_queue<node> pq;
bool found_goal = false;
pq.push(start);
while (!pq.empty()) {
node t = pq.top();pq.pop();
// goal test
bool isgoal = true;
For(i, 0, k -1)
if(t.idx[i] != xi[i].length())
{
isgoal = false;
break;
}
if(isgoal){
found_goal = true;
parent[conv_hash(t.idx)] =t.parent;
end = t;
break;
}
// goal test ends
if(present(parent, conv_hash(t.idx))) continue;
parent[conv_hash(t.idx)] =t.parent;
For(i, 1, (1<<k) - 1)
{
node child;
bool flag = 0;
string curr_state = "";
For(j, 0, k-1) child.idx[j] = (t.idx[j] +
g_next[i-1][j]);
For(j, 0, k-1){
if(child.idx[j] > xi[j].length()) {flag = 1;
break;}
else if(g_next[i-1][j] == 0){
curr_state = curr_state + "-";
child.cost += cc;
}
else if(g_next[i-1][j] == 1)
curr_state = curr_state + xi[j]
[t.idx[j]];
}
if(flag == 1) continue;
child.parent = conv_hash(t.idx);
child.cost += t.cost + cost(curr_state);

pq.push(child);

}
// search ends
vs xi_result(k);
if(found_goal){
cout << end.cost<<endl;
// reconstruct the solution
ll val = conv_hash(end.idx);
//For(i, 0, k-1) cout << end.idx[i] << " ";
while (val != 0) {
vi par = hash_to_ve(parent[val]);
vi curr = hash_to_ve(val);
vi s = sub(par,curr);
For(i, 0, k-1) xi_result[i] = ((s[i] == 0)?'-':
(xi[i][par[i]])) + xi_result[i];
val = parent[val];
}
//For(i, 0, k-1) cout<<xi_result[i]<<endl;
}
cout << endl << h2(0,1,3,3);
}

Das könnte Ihnen auch gefallen