【FZU】Problem 2217 Taxi 【暴力状压dp】

传送门:【FZU】Problem 2217 Taxi

my   code:

///*
#include <stdio.h>
#include <string.h>
#include <algorithm>
//*/
//#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 25 ;
const int MAXM = 7005 ;

struct Node {
    int t , x , y , p ;
    bool operator < ( const Node& a ) const {
        return t < a.t ;
    }
} ;

Node a[MAXN] ;
int G[MAXN][MAXN] ;
int idx[MAXM] , state[1 << 20] , num[MAXM] , cnt ;
int dp[20][MAXM] ;
int S[5] , vis[5] , top ;
int n , m , K ;
int ans ;

void dfs ( int cur , int x , int s ) {
    if ( cur > K ) return ;
    if ( x == m ) {
        idx[cnt] = s ;
        num[cnt] = cur ;
        state[s] = cnt ++ ;
        return ;
    }
    dfs ( cur , x + 1 , s << 1 ) ;
    dfs ( cur + 1 , x + 1 , s << 1 | 1 ) ;
}

void dfs2 ( int cur , int now , int val , int pos , int s , int x ) {
    if ( cur == top ) {
        if ( s == 0 ) ans = max ( ans , val ) ;
        for ( int i = x ; i < m ; ++ i ) {
            int k = state[s | ( 1 << i )] ;
            if ( now + G[pos][a[i].x] <= a[i].t ) dp[i][k] = max ( dp[i][k] , val ) ;
        }
        return ;
    }
    for ( int i = 0 ; i < top ; ++ i ) if ( !vis[i] ) {
        vis[i] = 1 ;
        int v = S[i] , nxt = now + G[pos][a[v].y] ;
        dfs2 ( cur + 1 , nxt , val + max ( a[v].p + a[v].t - nxt , 0 ) , a[v].y , s , x ) ;
        vis[i] = 0 ;
    }
}

void solve () {
    cnt = 0 ;
    scanf ( "%d%d%d" , &n , &m , &K ) ;
    dfs ( 0 , 0 , 0 ) ;
    for ( int i = 0 ; i < m ; ++ i ) {
        scanf ( "%d%d%d%d" , &a[i].t , &a[i].x , &a[i].y , &a[i].p ) ;
        a[i].x -- ;
        a[i].y -- ;
    }
    sort ( a , a + m ) ;
    for ( int i = 0 ; i < n ; ++ i ) {
        for ( int j = 0 ; j < n ; ++ j ) {
            scanf ( "%d" , &G[i][j] ) ;
        }
    }
    for ( int k = 0 ; k < n ; ++ k ) {//floyd
        for ( int i = 0 ; i < n ; ++ i ) {
            for ( int j = 0 ; j < n ; ++ j ) {
                G[i][j] = min ( G[i][j] , G[i][k] + G[k][j] ) ;
            }
        }
    }
    clr ( dp , -1 ) ;
    ans = 0 ;
    for ( int i = 0 ; i < m ; ++ i ) {
        if ( G[0][a[i].x] <= a[i].t ) dp[i][state[1 << i]] = max ( dp[i][state[1 << i]] , 0 ) ;
        for ( int j = 1 ; j < cnt ; ++ j ) if ( dp[i][j] != -1 ) {
            int st = idx[j] ;
            for ( int k = st ; ~k ; k = k ? ( st & ( k - 1 ) ) : -1 ) {
                top = 0 ;
                int tmp = 0 ;
                for ( int l = 0 ; l < m ; ++ l ) {
                    if ( k & ( 1 << l ) ) S[top ++] = l ;
                    else if ( st & ( 1 << l ) ) ++ tmp ;
                }
                if ( tmp < K ) dfs2 ( 0 , a[i].t , dp[i][j] , a[i].x , st ^ k , i + 1 ) ;
            }
        }
    }
    printf ( "%d\n" , ans ) ;
}

int main () {
    int T ;
    scanf ( "%d" , &T ) ;
    for ( int i = 1 ; i <= T ; ++ i ) {
        solve () ;
    }
    return 0 ;
}

你可能感兴趣的:(【FZU】Problem 2217 Taxi 【暴力状压dp】)