poj2288
2014-12-29 16:46
375 查看
题目大意:求一条哈密顿回路,但是权值计算不同,包括三部分:1.经过的所有点的权值相加。2.经过的连续两个点的权值的乘积。3.能够构成三角型的连续三个点的乘积。这些全部加起来就是这条回路的总权值。输出最大权值和这个最大权值的路线有多少条
解题思路:先处理好两相连的情况,如果i与j,我们很容易得到dp[i][j][s]=(v[i]+v[j]+v[i]*v[j]);这相当于dp的初始化,i与j表 示相连的两点,s表示当前走过的状态,接下来就是处理三点之间的关系了,当i与j满足相连关系时,枚举第 三个点的所有情况,当他满足与j相连是,增加量ans=v[k]*v[j]+v[k],
若果k还满足了与i相连,那么 ans=ans+v[i]*v[j]*v[k];由于此题还要记录这样的路线数量,因此我们还需要一的三维数组记录到达各个路线的条数
当满足相等的情况是,num数组就应该相加进行更新,当新的路线权值大于旧的路线是,我们只需覆盖跟新,(想想为什么)(注意转移时的各种满足条件,不要漏写!!!)
代码:
解题思路:先处理好两相连的情况,如果i与j,我们很容易得到dp[i][j][s]=(v[i]+v[j]+v[i]*v[j]);这相当于dp的初始化,i与j表 示相连的两点,s表示当前走过的状态,接下来就是处理三点之间的关系了,当i与j满足相连关系时,枚举第 三个点的所有情况,当他满足与j相连是,增加量ans=v[k]*v[j]+v[k],
若果k还满足了与i相连,那么 ans=ans+v[i]*v[j]*v[k];由于此题还要记录这样的路线数量,因此我们还需要一的三维数组记录到达各个路线的条数
当满足相等的情况是,num数组就应该相加进行更新,当新的路线权值大于旧的路线是,我们只需覆盖跟新,(想想为什么)(注意转移时的各种满足条件,不要漏写!!!)
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define LL __int64 LL dp[15][15][1<<13],num[15][15][1<<13]; int map[13][13],a1[15],v[15]; int main() { int T,n,m; scanf("%d",&T); while(T--) { int i,j,k,s,a,b; memset(map,0,sizeof(map)); memset(num,0,sizeof(num)); memset(dp,0,sizeof(dp)); scanf("%d%d",&n,&m); for(i=0;i<n;i++) { scanf("%d",&v[i]); } for(i=0;i<m;i++) { scanf("%d%d",&a,&b); a--,b--; map[a][b]=map[b][a]=1; } a1[0]=1; for(i=1;i<=13;i++) { a1[i]=a1[i-1]*2; } if(n==1)//只有一个点时,直接输出第一个点的点权 { printf("%d 1\n",v[0]); } else { for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(map[i][j]==0||i==j)continue; int s=(a1[i]|a1[j]); dp[i][j][s]=(v[i]+v[j]+v[i]*v[j]); num[i][j][s]=1;//记录满足条件的路径有几条 } } for(s=0;s<a1 ;s++) { for(i=0;i<n;i++) { if((s&a1[i])==0)continue; for(j=0;j<n;j++) { if(i==j||(s&a1[j])==0||dp[i][j][s]==0)continue; if(map[i][j]==0)continue; for(k=0;k<n;k++) { if(i==k||j==k||(s&a1[k])!=0||map[k][i]==0)continue; int t=s|a1[k]; LL ans1=v[i]*v[k]+v[k];//k与i相连 if(map[k][j]!=0)//k与j相连满足,那么i,j,k三点两两相连 { ans1+=v[i]*v[j]*v[k]; } if(dp[k][i][t]<dp[i][j][s]+ans1) { dp[k][i][t]=dp[i][j][s]+ans1; num[k][i][t]=num[i][j][s]; } else if(dp[k][i][t]==dp[i][j][s]+ans1) { dp[k][i][t]=dp[i][j][s]+ans1; num[k][i][t]+=num[i][j][s]; } } } } } LL ans=0,tol=0; for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(ans<dp[i][j][a1 -1]) { ans=dp[i][j][a1 -1]; tol=num[i][j][a1 -1]; } else if(ans==dp[i][j][a1 -1]) { ans=dp[i][j][a1 -1]; tol+=num[i][j][a1 -1]; } } } printf("%I64d %I64d\n",ans,tol/2);//除以2的原因是因为无向图,而i到j,j到i我们各算了一次 } } return 0; }
相关文章推荐
- poj2288(状压dp)
- poj2288 类哈密顿路
- 状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- 状态压缩DP总结【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- 状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- POJ2288 Islands and Bridges
- POJ2288 Islands and Bridges (DP)
- POJ2288(状压DP)
- 状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- 状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- 状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- poj2288 状压dp
- POJ2288
- 状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- poj2288之求有多少条哈密顿路
- POJ2288题解
- POJ2288:Islands and Bridges(状态压缩)
- poj2288(Islands and Bridges) 状压DP
- poj2288汉密尔顿路
- POJ2288 Islands and Bridges