燙燙燙燙燙燙燙燙燙燙燙燙燙

cjwen6發表於2024-03-22

CF1239E Turtle

直接退火會被後三個點卡,好像數都是二的次冪,卡的原理未知。

發現性質:當第一行放哪些數第二行放哪些數確定時,第一行從小到大排序,第二行從大到小排序,一定是最優的。

https://codeforces.com/contest/1239/submission/216230291

用 nmw 的號交的。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<random>
#include<ctime>
#include<algorithm>
#include<cmath>

using namespace std;

const int N = 30, M = 60;

int n, a[3][N];
int f[3][N];
int b[3][N], c[3][N];
int tp[M];

int ga(){
    sort(b[1]+1, b[1]+n+1);
    sort(b[2]+1, b[2]+n+1, greater<int>());
    for(int i = 1; i <= 2; i++){
        for(int j = 1; j <= n; j++){
            f[i][j] = max(f[i-1][j], f[i][j-1]) + b[i][j];
        }
    }
    return f[2][n];
}

mt19937 mrd(time(NULL));

int rd(int x, int y){
    return mrd()%(y-x+1)+x;
}

int zans, ans, tans;

void SA(){
    for(double T = 5000000; T >= 1e-13; T *= 0.999995){
        int x = rd(1, n), y = rd(1, n);
        swap(b[1][x], b[2][y]);
        tans = ga();
        if(tans < ans){
            ans = tans;
            if(tans < zans){
                zans = tans;
                for(int i = 1; i <= 2; i++){
                    for(int j = 1; j <= n; j++){
                        c[i][j] = b[i][j];
                    }
                }
            }
        }else{
            if(exp((ans-tans)/T) >= (double)rand()/RAND_MAX){
                ans = tans;
            }else{
                swap(b[1][x], b[2][y]);
            }
        }
    }
}

int main(){

    scanf("%d", &n);
    for(int i = 1; i <= 2; i++){
        for(int j = 1; j <= n; j++){
            scanf("%d", &a[i][j]);
            tp[(i-1)*n+j] = a[i][j];
        }
    }

    shuffle(tp+1, tp+1+2*n, mrd);
    for(int i = 1; i <= 2; i++){
        for(int j = 1; j <= n; j++){
            b[i][j] = tp[(i-1)*n+j];
        }
    }
    ans = ga();
    zans = ans;
    for(int i = 1; i <= 2; i++){
        for(int j = 1; j <= n; j++){
            c[i][j] = b[i][j];
        }
    }

    SA();

    for(int i = 1; i <= 2; i++){
        for(int j = 1; j <= n; j++){
            printf("%d ", c[i][j]);
        }
        puts("");
    }

    return 0;
}

CF730I

直接退火最高成績是 Wrong answer on test 89。

https://codeforces.com/contest/730/submission/216227556