POJ 2288 Islands and Bridges 状态压缩DP
来源:互联网 发布:pl2303hx数据手册 编辑:程序博客网 时间:2024/06/05 03:00
题意:给出n个岛和它们之间联通的m条路径,给出权值的计算方法,求权值最大哈密顿回路的权值和数量。
n<=13.
权值的计算方法为:
1.经过的所有点的权值之和;
2.经过的连续的两个点的权值的乘积;
3.能够组成三角形的三个点的权值的乘积。
根据岛是否走过最多有(1<<13)种状态。
dp[s][i][j] = max{ dp[s][i][j] , dp[s’][j][k] + tmp };
tmp = val[i]*val[j] + val[i];
if(i,j,k能够组成三角形) tmp += (val[i]*val[j]*val[k]);
对于路径的数量,如果更新dp[s][i][j],则更新num[s][i][j] = num[s’][j][k];
如果不更新dp[s][i][j],但是 dp[s][i][j] == dp[s’][j][k] + tmp,
则num[s][i][j] += num[s’][j][k].
路径数量最后要除以2,因为反向的路径是一样的,不能重复计算。
s表示当前的状态,i表示当前所在的岛,j表示上一步走的岛,k是所有岛中任意符合要求的岛。
#include <iostream>#include <cmath>#include <algorithm>#include <cstring>using namespace std;const int n = 13;const int maxn = 1<<13;int edge[n][n];int dp[maxn][n][n];int val[n];long long num[maxn][n][n];int N,M;int main(){ int T; cin>>T; while(T--){ cin>>N>>M; for(int i = 0;i < N;i++) cin>>val[i]; int x,y; memset(edge,0,sizeof(edge)); for(int i = 0;i < M;i++){ cin>>x>>y; edge[x-1][y-1] = edge[y-1][x-1] = 1; } if(N == 1) {cout<<val[0]<<" "<<"1"<<endl;continue;} memset(dp,-1,sizeof(dp)); memset(num,0,sizeof(num)); for(int i = 0;i < N;i++) for(int j = 0;j < N;j++){ if(i != j&&edge[i][j]){//初始化dp和num, //将走过任意一条边能够到达的状态的dp和num初始化。 dp[(1<<i)|(1<<j)][i][j] = val[i] + val[j] + val[i] * val[j]; num[(1<<i)|(1<<j)][i][j] = 1; } } for(int s = 0;s < (1<<N);s++){//枚举状态 for(int i = 0;i < N;i++){ if((s&(1<<i)) == 0) continue; for(int j = 0;j < N;j++){ if(((s&(1<<j))==0)||i == j||!edge[i][j]) continue; for(int k = 0;k < N;k++){ if(((s&(1<<k))==0)||i == k||j == k) continue; int newS = s-(1<<i); if(dp[newS][j][k] == -1) continue;//若为-1, //则表示不存在路径从第k座岛到达第j座岛 int tmp = val[i]*val[j]+val[i];//求出tmp值 if(edge[i][k]) //i,k之间有边,表示能够组成三角形,更新tmp tmp += val[i] * val[j] * val[k]; if(dp[s][i][j] < dp[newS][j][k] + tmp){ dp[s][i][j] = dp[newS][j][k] + tmp; num[s][i][j] = num[newS][j][k]; } else if(dp[s][i][j] == (dp[newS][j][k] + tmp)){ num[s][i][j] += num[newS][j][k]; } } } } } long long ans = -1,Num = 0; int p = (1<<N) - 1; for(int i = 0;i < N;i++){ for(int j = 0;j < N;j++){ if(i == j||!edge[i][j]) continue; if(dp[p][i][j] > ans){ ans = dp[p][i][j]; Num = num[p][i][j]; } else if(dp[p][i][j] == ans){ Num += num[p][i][j]; } } } if(ans == -1) cout<<"0"<<" "<<"0"<<endl; else cout<<ans<<" "<<Num/2<<endl; } return 0;}
0 0
- poj 2288 Islands and Bridges解题报告-状态压缩dp
- POJ 2288 Islands and Bridges 状态压缩DP
- POJ-2288 Islands and Bridges 状态压缩DP TSP
- poj 2288 状态压缩dp Islands and Bridges
- 【汉密尔顿、DP|状态压缩】POJ-2288 Islands and Bridges
- POJ 2288 Islands and Bridges 状态压缩DP
- POJ 2288 Islands and Bridges(状态压缩)
- Poj 2288 Islands and Bridges 状态压缩
- poj2288 Islands and Bridges 状态压缩dp
- pku 2288 Islands and Bridges(状态压缩DP)
- poj 2288 Islands and Bridges 状态压缩dp(附详细注释)
- Islands and Bridges - POJ 2288 状压dp
- 状压DP poj 2288 Islands and Bridges
- poj 2288 Islands and Bridges(状压dp)
- poj 2288 Islands and Bridges(状压dp)
- poj 2288 Islands and Bridges 状压dp
- poj 2288 Islands and Bridges 状压dp
- POJ 2288 Islands and Bridges(状压dp)
- Android 性能优化
- C++面试笔试题目(选2)(字符串,原码反码补码)
- AJAX跨域访问
- 第十一周项目1层次遍历算法的验证
- lua table访问的元方法
- POJ 2288 Islands and Bridges 状态压缩DP
- category添加成员变量
- Java将Unix时间戳转换成指定格式日期
- Java基础面试题笔记(2)
- 每天00:00:01循环执行定时任务
- iOS多线程GCD
- 移动端(html5)Safari下用keyup实时监控input值的变化无效
- ——黑马程序员——OC中block访问外部变量
- JSP总结(经典)