【状压dp】Islands and Bridges
| Time Limit: 4000MS | Memory Limit: 65536K | |
| Total Submissions: 11034 | Accepted: 2866 |
Description
Suppose there are n islands. The value of a Hamilton path C1C2...Cn is calculated as the sum of three parts. Let Vi be the value for the island Ci. As the first part, we sum over all the Vi values for each island in the path. For the second part, for each edge CiCi+1 in the path, we add the product Vi*Vi+1. And for the third part, whenever three consecutive islands CiCi+1Ci+2 in the path forms a triangle in the map, i.e. there is a bridge between Ci and Ci+2, we add the product Vi*Vi+1*Vi+2.
Most likely but not necessarily, the best triangular Hamilton path you are going to find contains many triangles. It is quite possible that there might be more than one best triangular Hamilton paths; your second task is to find the number of such paths.
Input
Output
Note: A path may be written down in the reversed order. We still think it is the same path.
Sample Input
2
3 3
2 2 2
1 2
2 3
3 1
4 6
1 2 3 4
1 2
1 3
1 4
2 3
2 4
3 4
Sample Output
22 3
69 1
Source
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
#define LL long long
inline LL read(){
LL x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
} const int MAXN=100001;
const int INF=999999;
int N,M;
int T;
LL C[101];
bool e[101][101];
LL dp[9001][15][15];
LL num[9001][15][15]; int main(){
T=read();
while(T--){
LL ans=0;
memset(e,false,sizeof(e));
memset(dp,-1,sizeof(dp));
memset(num,0,sizeof(num));
N=read(),M=read();
for(int i=1;i<=N;i++) C[i]=read();
for(int i=1;i<=M;i++){
int u=read(),v=read();
e[u][v]=e[v][u]=true;
}
if(N==1){
printf("%lld %lld\n",C[1],1);
continue;
}
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
if(i!=j&&e[i][j]) {
dp[(1<<(i-1))+(1<<(j-1))][i][j]=(long long)C[i]+C[j]+C[i]*C[j];
num[(1<<(i-1))+(1<<(j-1))][i][j]=1;
}
for(int i=0;i<(1<<N);i++){
for(int j=1;j<=N;j++){
if(!((i>>(j-1))&1)) continue;
for(int k=1;k<=N;k++){
if(k==j||!e[k][j]||!((i>>(k-1))&1)) continue;
for(int p=1;p<=N;p++){
if(!((i>>(p-1))&1)||p==k||p==j||!e[p][k]) continue;
if(dp[i-(1<<(j-1))][k][p]==-1) continue;
LL t1=(long long)dp[i-(1<<(j-1))][k][p]+C[j]*C[k]+C[j];
if(e[p][j]) t1=(long long)dp[i-(1<<(j-1))][k][p]+C[j]*C[k]+C[j]*C[k]*C[p]+C[j];
if(t1>dp[i][j][k]){
dp[i][j][k]=t1;
num[i][j][k]=num[i-(1<<(j-1))][k][p];
}
else if(dp[i][j][k]==t1) num[i][j][k]+=num[i-(1<<(j-1))][k][p];
}
}
}
}
LL tmp=0;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
if(i!=j)
if(ans<dp[(1<<N)-1][i][j]) ans=dp[(1<<N)-1][i][j],tmp=num[(1<<N)-1][i][j];
else if(ans==dp[(1<<N)-1][i][j]) tmp+=num[(1<<N)-1][i][j];
printf("%lld %lld\n",ans,tmp/2);
}
}
【状压dp】Islands and Bridges的更多相关文章
- Islands and Bridges(POJ2288+状压dp+Hamilton 回路)
题目链接:http://poj.org/problem?id=2288 题目: 题意:求Hamilton 路径权值的最大值,且求出有多少条权值这么大的Hamilton路径. 思路:状压dp,dp[i] ...
- CH0103最短Hamilton路径 & poj2288 Islands and Brigdes【状压DP】
虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位 \((n >> ...
- 状压DP天秀
状压DP,依靠的是把状态用某种压缩方式表示出来进而DP,大多数时候是二进制状压. 直接看例题吧. 一双木棋 九尾狐吃棉花糖 islands and bridges 愤怒的小鸟 芯片 ...
- BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS
BZOJ_3049_[Usaco2013 Jan]Island Travels _状压DP+BFS Description Farmer John has taken the cows to a va ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
随机推荐
- python学习笔记(九)之字符串
定义字符串 >>> mystring = 'Hello Python' >>> name = str('Mountain') >>> mystri ...
- 20、redis和memcached比较?
1.Redis和Memcache都是将数据存放在内存中,都是内存数据库.不过memcache还可用于缓存其他东西,例如图片.视频等等: 2.Redis不仅仅支持简单的k/v类型的数据,同时还提供lis ...
- Html5_sessionStrong和localStorage的灵活使用
谈谈这两个属性sessionStrong和localStorage是Html5新增点属性,用来记录一些数据在浏览器. 两者的区别sessionStrong存储的数据是暂时的,浏览器关掉后,存储下来的数 ...
- recycleView实现item点击更改该item颜色,其它item颜色变回
项目中需要横向滚动效果,按照以前的思路,我会写一个ScrollView,里边加一个LinearLayout,在代码中动态加入控件,然后动态删除或者改变颜色,现在android有了新控件Recycler ...
- python基础===理解Class的一道题
解题如下: from random import randint class Die(): def __init__(self,sides=6): self.sides = sides def rol ...
- 基于 Arduino 开发板,这款插座是可编程且开源的
基于 Arduino 开发板,这款插座是可编程且开源的 https://www.oschina.net/news/74861/open-source-socket https://github.com ...
- 基数排序c++实现
基数排序:是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较.由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数.但在 ...
- 设计模式之笔记--装饰模式(Decorator)
装饰模式(Decorator) 定义 装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 类图 描述 Component:被装饰者和装饰者 ...
- springboot项目的搭建
原文链接:http://www.cnblogs.com/winner-0715/p/6666302.html 后续完善(附图及详细过程)
- MySQL-5.5.49安装、多实例、主从复制
源码安装mysql yum install ncurses-devel libaio-devel -y mkdir /server/tools -p cd /server/tools wget htt ...