Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <vector>
- #include <queue>
- #include <algorithm>
- #include <string>
- #include <stack>
- #include <set>
- #include <map>
- #define pii pair <int,int>
- using namespace std;
- /*
- решение:
- 1)сделать граф
- 2)найти мин гамильтонов путь
- 3) ответ = мин гамильтонов путь + расстояние, чтобы дойти до стартовой вершины этого пути
- ЕСЛИ ТАКОЕ НЕ ЗАЙДЁТ хотя бы на 90 баллов:
- )посчитать за О(n^2), из какой вершины выгоднее стартовать = вершина start
- )посчитать минимальные гамильтоновы пути из каждой вершины
- )перебрать все сочетания за O(n) : (x, y), где x - длина пути до стартовой вершины, y - длина мин гамильтонова пути
- */
- using ll = long long;
- using ld = long double;
- void cv(vector <int> &v){
- for (auto x: v) cout<<x<<' ';
- cout<<"\n\n";
- }
- int N;
- int inf = 1e9;
- vector <int> a, b;
- vector <vector <int>> G;
- void cG(){
- for (int i = 0; i < N; ++i){
- for (int j = 0; j < N; ++j){
- cout<<"("<<i+1<<","<<j+1<<") = "<<G[i][j]<<"\n";
- }cout<<"\n";
- }cout<<"\n";
- }
- int mk(int x, int y){
- int idx, idy, r = 0;
- for (int i=0;i<N;++i){
- if (a[i] == x){
- idx = i;
- }
- else if (a[i] == y){
- idy = i;
- }
- }
- r += abs(idx - idy);
- for (int i=0;i<N;++i){
- if (b[i] == x){
- idx = i;
- }
- else if (b[i] == y){
- idy = i;
- }
- }
- r += abs(idx - idy);
- return r;
- }
- vector <vector <int> > dp;
- string two(int x){
- string r="";
- while (x > 0){
- r += ((x % 2) + 48);
- x /= 2;
- }
- while (r.size() != N){
- r += '0';
- }reverse(r.begin(), r.end());
- return r;
- }
- void wrk(){
- for (int msk = 1; msk < (1 << N); ++msk){
- //cout<<"mask = "<<two(msk)<<"\n";
- for (int i = 0; i < N; ++i){
- // cout<<"1<<i = "<< (1<<i)<<"\n";
- //cout<<"i = "<<two(1<<i);
- //cout<<"msk & (1 << i) = "<<msk & (1 << i)<<"\n";
- if (!(msk & (1 << i))) {
- continue;
- }
- for (int j = 0; j < N; ++j){
- if (msk & (1 << j)) continue;
- //cout<<"j = "<<two(1<<j)<<"\n";
- dp[msk | (1 << j)][j] = min(dp[msk | (1 << j)][j], dp[msk][i] + G[i][j]);
- }
- //cout<<"\n";
- }//cout<<"\n";
- }
- }
- void cdp(){
- for (auto x: dp){
- for (auto y: x) cout<<y<<' ';
- cout<<"\n";
- }cout<<"\n";
- }
- vector <int> srt_dst;
- int v=0;
- int opt(){
- int idx,dst;
- for (int i = 0; i < N; ++i){
- idx = 0;
- dst = 0;
- while (a[idx] != i){
- idx++;
- }
- dst += idx;
- idx = 0;
- while (b[idx] != i){
- idx++;
- }
- dst += idx;
- srt_dst[i] = dst;
- }
- //cout<<"srt_dst\n";
- //cv(srt_dst);
- int mn = inf, mn_v = 1;
- for (int i = 0; i < N; ++i){
- /*cout<<"i = "<<i<<'\n';
- cout<<"dp[1<<N - 1][i] = "<<dp[(1<<N) - 1][i]<<'\n';
- cout<<"srt_dst[i] = "<<srt_dst[i]<<'\n';*/
- if (dp[(1<<N) - 1][i] + srt_dst[i] < mn){
- mn = dp[(1<<N) - 1][i] + srt_dst[i];
- mn_v = i;
- }
- //cout<<"mn = "<<mn<<'\n';
- }
- return mn_v;
- }
- vector <int> gml; //gamilton way minimum
- void way(){
- int msk = (1<<N) - 1, j = v;
- gml.push_back(v);
- while (gml.size() < N){
- //cout<<"msk = "<<two(msk)<<'\n';
- for (int i = 0; i < N; ++i){//xor ^ - ?
- if (dp[msk][j] == dp[msk ^ (1<<j)][i] + G[i][j]){
- gml.push_back(i);
- msk = msk ^ (1 << j);
- j = i;
- break;
- }
- }
- //cout<<"way\n";
- //cv(gml);
- }
- //cout<<"way\n";
- //cv(gml);
- }
- string ans = "";
- void draw(){
- vector <int> aid(N), bid(N);
- for (int i = 0; i < N;++i){
- // cout<<"i a[i] b[i] = "<<i<<' '<<a[i]<<' '<<b[i]<<'\n';
- aid[a[i]] = i;
- bid[b[i]] = i;
- }
- /*cout<<"aid\n";
- cv(aid);
- cout<<"bid\n";
- cv(bid);*/
- //vector <int> gone;
- int ax=0, bx=0, now=0;//indexes
- while (now < N){
- //cout<<"gml[now] = "<<gml[now]<<'\n';
- while (a[ax] != gml[now]){
- if (aid[gml[now]] < aid[a[ax]]){
- ax--;
- ans += 'L';
- }
- else {
- ax++;
- ans += 'R';
- }
- }
- while (b[bx] != gml[now]){
- if (bid[gml[now]] < bid[b[bx]]){
- bx--;
- ans += 'l';
- }
- else{
- bx++;
- ans += 'r';
- }
- }
- now++;
- //cout<<"ans = "<<ans<<'\n';
- }
- //cout<<"ans\n";
- //cout<<ans<<"\n\n";
- }
- int main()
- {
- /*ios::sync_with_stdio(0);
- cin.tie(0);
- cout.tie(0);*/
- cin>>N;
- G.resize(N, vector <int> (N, inf));
- a.resize(N, inf); b.resize(N, inf);
- for (int i = 0; i < N; ++i){
- int inb; cin>>inb; inb--;
- //cout<<"inb = "<<inb<<"\n";
- a[i] = i;
- b[inb] = i;
- }
- //cv(a);
- //cv(b);
- for (int i = 0; i < N; ++i){
- for (int j = 0; j != i && j < N; ++j){
- G[i][j] = G[j][i] = mk(i, j);
- }
- }
- //cG();
- //мин гамильтонов путь
- dp.assign(1<<N, vector <int> (N, inf));
- for (int i = 0; i < N; ++i){
- dp[1<<i][i] = 0;
- }
- wrk();
- //cdp();
- srt_dst.assign(N, -1);
- v = opt(); // most effective ending vertex
- //cout<<"v = "<<v<<'\n';
- way();
- draw();
- //reverse(ans.begin(),ans.end());
- cout<<ans<<'\n';
- }
- /*
- 5
- 1 3 5 2 4
- 6
- 3 6 4 1 5 2
- lLLlllRrRRllRrrrRrr
- */
Add Comment
Please, Sign In to add comment