Main topic:
There are n islands, so VI is the weighted value of the Island CI. A Hamilton path C1,C2,C3 ... The value of CN is 3 parts
In the first part, the weights of the islands in the path are added, and the second part (CI,CJ) on each side, plus all the VI*VJ
The third part, if 3 consecutive cities can form a 3-point unicom, then add VI*VJ*VK
Find a path that maximizes its weight and record how many paths can be reached for the maximum weight value
1->2->3, 3->2->1 as the same path
There are up to 13 cities, so use 2 to indicate whether to reach the current location of the city
Here Dp[i][k][j] means that the last two cities to reach the I state are j,k, so that the maximum weight that can be reached
Dp[i| ( 1<< (t-1)][j][t] = max{dp[i| ( 1<< (t-1)][j][t], dp[i][k][j]+val[t]+val[j]*val[t]+ edge[k][t]?val[j]*val[k]*val[t]:0}
Note that each time the DP value is updated, the number of paths that reach the current state is recorded cnt[i][k][j]
It's important to note that there is only one city to judge.
1#include <cstdio>2#include <cstring>3#include <iostream>4#include <cmath>5 using namespacestd;6 #defineN 147 #definell Long Long8 intn,m;9ll dp[1<<n][n][n], Val[n], cnt[1<<N][N][N];//CNT records the total number of possible methods in the current stateTen BOOLEdge[n][n]; One A voidGETDP () - { -memset (CNT,0,sizeof(CNT)); theMemset (DP,-1,sizeof(DP)); - intAll = (1<<n); -dp[0][0][0]=0, cnt[0][0][0]=0; - for(intI=1; I<=n; i++) dp[1<< (I-1)][0][i]=val[i],cnt[1<< (I-1)][0][i]=1; + for(intI=1; I<all; i++){ - for(intj=1; J<=n; J + +){ + if(! (i& (1<< (J-1))))Continue; A for(intk=0; K<=n; k++){ at if(k = =0&& (i!= (1<< (J-1))))Continue; - if(K==j | | (! (i& (1<< (K-1))) && k!=0))Continue; - if(dp[i][k][j]<0)Continue; - - for(intt=1; T<=n; t++){ - if(!edge[j][t] | | i& (1<< (t1)))Continue; inll v = dp[i][k][j]+val[t]+val[t]*Val[j]; - if(Edge[t][k]) v = v+val[j]*val[k]*Val[t]; to intStatus = i| (1<< (t1)); + if(dp[status][j][t]<0|| dp[status][j][t]<v) { -dp[status][j][t]=v; thecnt[status][j][t]=Cnt[i][k][j]; * } $ Else if(Dp[status][j][t] = =v) {Panax Notoginsengcnt[status][j][t]+=Cnt[i][k][j]; - } the //Debug + //print (status);cout<<endl; A //cout<<i<< "<<j<<" "<<k<<" "<<dp[status][k][t]<<endl; the } + } - } $ } $ } - - intMain () the { - //freopen ("a.in", "R", stdin);Wuyi intT; thescanf"%d", &T); - while(t--) Wu { -scanf"%d%d", &n, &m); About for(intI=1; I<=n; i++) scanf ("%i64d", val+i); $Memset (Edge,0,sizeof(Edge)); - intb; - for(intI=0; I<m; i++){ -scanf"%d%d", &a, &b); Aedge[a][b]=true; +edge[b][a]=true; the } - GETDP (); $ intAll= (1<<n); thell MAXN =-1, ans=0; the for(intI=0; I<=n; i++) the for(intj=0; J<=n; J + +) the { -Maxn=max (maxn,dp[all-1][i][j]); in } the if(MAXN = =-1){ thePuts"0 0"); About Continue; the } the for(intI=0; I<=n; i++) the for(intj=0; J<=n; J + +) + if(MAXN = = dp[all-1][I][J]) ans+=cnt[all-1][i][j]; - /** * To be aware that only one city is in the case of a special sentence **/ theprintf"%i64d%i64d\n", MAXN, ans/2? ans/2:1);Bayi } the return 0; the}
POJ 2288 Hamilton Loop DP Solution