【动态规划】[POJ 2288]Islands and Bridges

这倒题太坑了。。。简直。。。明明没有错误的代码就是A不了。。
题目分析另f(state,i,j) 表示在状态为state的情况下当前在i点前一个点是j点的所能够得到的最大的乘积那么很容易发现

f(state+(1<<k),k,i)=f(state,i,j)+v[k]+v[k]×v[i]|G[j][k]=0
或者
f(state+(1<<k),k,i)=f(state,i,j)+v[k]+v[k]×v[i]+v[k]×v[i]×v[j]|G[j][k]=1
其中G表示i,j是否连通,那么最终的答案就是
max{f((1<<n)1,i,j)}
这里i和j是需要枚举的,然后怎么寻找方案数量呢定义g(state,i,j)表示在状态为state的情况下当前在i点前一个点是j点的所能够得到的最大的乘积的方案数量那么
g(state+(1<<k),k,i)=g(state,i,j)|f(state+(1<<k),k,i)<f(state,i,j)+v[k]+v[k]×v[i]

在相等条件的情况下的时候
g(state+(1<<k),k,i)+=g(state,i,j)
剩下的就是注意代码了,如果一直Ac不了,删了重新写吧。。。

#include <cstdio>
#include <cstring>
using namespace std;
/*********/
typedef long long LL;
const int MAXN = 13;

int Map[MAXN+2][MAXN+2];
LL way[int(1<<MAXN)+2][MAXN+2][MAXN+2];
LL dp[int(1<<MAXN)+2][MAXN+2][MAXN+2];
LL v[MAXN+2], n, m;
/*********/
void DP(){
    memset(dp, -1, sizeof dp);
    memset(way, 0, sizeof way);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j) continue;
            if(!Map[i][j]) continue;
            dp[(1<<i)+(1<<j)][i][j] = v[i] * v[j] + v[i] + v[j];
            way[(1<<i)+(1<<j)][i][j] = 1;
        }
    }
    int Max = 1 << n;
    for(int state=0; state<Max; state++){
        for(int i=0; i<n; i++){
            if((state & (1 << i)) == 0) continue;
            for(int j=0; j<n; j++){
                if((state & (1 << j)) == 0) continue;
                if(i == j) continue;
                if(!Map[i][j]) continue;
                if(dp[state][j][i] == -1) continue;
                for(int k=0; k<n; k++){
                    if(k == i || k == j) continue;
                    if(!Map[j][k]) continue;
                    if((state & (1 << k)) != 0) continue;
                    int _state = state + (1 << k);
                    int tmp = dp[state][j][i] + v[k] + v[k] * v[j];
                    if(Map[i][k]) tmp += v[k] * v[j] * v[i];
                    if(tmp > dp[_state][k][j]){
                        dp[_state][k][j] = tmp;
                        way[_state][k][j] = way[state][j][i];
                    }else if(tmp == dp[_state][k][j])
                        way[_state][k][j] += way[state][j][i];
                }
            }
        }
    }
    long long ans=-1, wsum=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i == j || !Map[i][j]) continue;
            if(dp[Max-1][i][j] > ans){
                ans = dp[Max-1][i][j];
                wsum = way[Max-1][i][j];
            }else if(dp[Max-1][i][j] == ans)
                wsum += way[Max-1][i][j];
        }
    }
    printf("%I64d %I64d\n", ans==-1?0:ans, wsum/2);
}
int main(){
    int T, u, vp;
    scanf("%d", &T);
    while(T--){
        memset(Map,  0, sizeof Map);
        scanf("%I64d%I64d", &n, &m);
        for(int i=0; i<n; i++) scanf("%I64d", &v[i]);
        for(int i=0; i<m; i++){
            scanf("%d%d", &u, &vp);
            u --; vp --;
            Map[u][vp] = Map[vp][u] = 1;
        }
        if(n == 1) printf("%I64d 1\n", v[0]);
        else DP();
    }

    return 0;
}

posted on 2015-07-15 16:57  JeremyGuo  阅读(119)  评论(0编辑  收藏  举报

导航