POJ-3635: tanque lleno? Camino más corto + punto de desmontaje

análisis

Es un poco como
una pregunta que vi hace un tiempo sobre la división de puntos para encontrar la exponenciación rápida de la matriz de adyacencia. La forma más sencilla de hacer esto es tomar el jj restante para cada punto.El costo mínimo de gasolina por unidad j se procesa, y luego escrito así, sin duda, será pequeño, por lo que debemos hacer algunas optimizaciones.
Primero, pensemos por qué esta simple idea se agotará, porque no la necesitamos en muchos estados, pero lo tomamos. Está procesado, por lo que tenemos que reducir el estado
quenecesitamos tanto como sea posible.Podemos tratar cada unidad de gasolina como un estado y realizar una operación de dos pasos en cada paso. Primero agregue una unidad de aceite al estado actual, o simplemente dejar sin repostar., Utilice la cola de prioridad para mantener el estado menos costoso de todos los estados, a fin de evitar una gran cantidad de cálculos de estado innecesarios

Código


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 55,M = 505;
const ll mod= 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
    
    char c=getchar();T x=0,f=1;while(!isdigit(c)){
    
    if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
    
    x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
int gcd(int a,int b){
    
    return (b>0)?gcd(b,a%b):a;}
int tr[M][4],idx;
int f[M][11 * 11 * 11 * 11 + 10];
char str[M];
int n;
int num[5],q[M];
int cnt[M],ne[M],b[5];

void init(){
    
    
    memset(tr,0,sizeof tr);
    memset(ne,0,sizeof ne);
    memset(f,-0x3f,sizeof f);
    memset(cnt,0,sizeof cnt);
    memset(num,0,sizeof num);
    memset(b,0,sizeof b);
    idx = 0;
}

int get(char x){
    
    
    if(x == 'A') return 0;
    if(x == 'T') return 1;
    if(x == 'G') return 2;
    return 3;
}

void insert(){
    
    
    int p = 0;
    for(int i = 0;str[i];i++){
    
    
        int t = get(str[i]);
        if(!tr[p][t]) tr[p][t] = ++idx;
        p = tr[p][t];
    }
    cnt[p]++;
}

void build(){
    
    
    int hh = 0,tt = -1;
    for(int i = 0;i < 4;i++)
        if(tr[0][i]) q[++tt] = tr[0][i];
    while(hh <= tt){
    
    
        int t = q[hh++];
        for(int i = 0;i < 4;i++){
    
    
            int c = tr[t][i];
            if(!c) tr[t][i] = tr[ne[t]][i];
            else{
    
    
                ne[c] = tr[ne[t]][i];
                q[++tt] = c;
                cnt[c] += cnt[ne[c]];
            }
        }   
    }
}



int main(){
    
    
    int T = 0;
    while(scanf("%d",&n) && n){
    
    
        init();
        for(int i = 0;i < n;i++){
    
    
            scanf("%s",str);
            insert();
        }
        build();
        scanf("%s",str);
        for(int i = 0;str[i];i++){
    
    
            int t = get(str[i]);
            num[t]++;
        }
        b[0] = 1;
        b[1] = num[0] + 1;
        b[2] = b[1] * (num[2] + 1);
        b[3] = b[2] * (num[3] + 1);
        f[0][0] = 0;
        for(int A = 0;A <= num[0];A++)
            for(int T = 0;T <= num[1];T++)
                for(int G = 0;G <= num[2];G++)
                    for(int C = 0;C <= num[3];C++)
                        for(int i = 0;i <= idx;i++){
    
    
                            int st = A + T * b[1] + G * b[2] + C * b[3];
                            if(f[i][st] == -INF) continue;
                            for(int j = 0;j <= 3;j++){
    
    
                                if(j == 0 && A >= num[0]) continue;
                                if(j == 1 && T >= num[1]) continue;
                                if(j == 2 && G >= num[2]) continue;
                                if(j == 3 && C >= num[3]) continue;
                                int t = st + b[j];
                                int tj = tr[i][j];
                                f[tj][t] = max(f[i][st] + cnt[tj],f[tj][t]);
                            }
                        }
        int ans = 0;
        int res = num[0] + num[1] * b[1] + num[2] * b[2] + num[3] * b[3];
        for(int i = 0;i <= idx;i++) ans = max(ans,f[i][res]);
        printf("Case %d: %d\n",++T,ans);
    }
    return 0;
}

/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/




Supongo que te gusta

Origin blog.csdn.net/tlyzxc/article/details/114580126
Recomendado
Clasificación