题目:http://poj.org/problem?id=2288

不知为什么记忆化搜索就是WA得不得了!

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=,Lm=(<<)+;
int q,n,m,lm,v[N];
ll ans,prn,dp[Lm][N][N],f[Lm][N][N];
bool b[N][N];
ll dfs(int S,int x,int px)
{
if(dp[S][x][px]!=-)return dp[S][x][px];
if(S==lm){f[S][x][px]=;return dp[S][x][px]=;}
for(int i=;i<=n;i++)
if(b[x][i]&&(S&(<<(i-)))==)
{
int D=(S|(<<(i-)));
ll w=dfs(D,i,x)+v[i]+v[x]*v[i]+(b[px][i]?v[px]*v[x]*v[i]:);
if(w>dp[S][x][px])
dp[S][x][px]=w,f[S][x][px]=f[D][i][x];
else if(w==dp[S][x][px])
f[S][x][px]+=f[D][i][x];
}
return dp[S][x][px];
}
int main()
{
scanf("%d",&q);
while(q--)
{
memset(b,,sizeof b);
scanf("%d%d",&n,&m);lm=(<<n)-;
for(int i=;i<=n;i++)scanf("%d",&v[i]);
int x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d",&x,&y);b[x][y]=;b[y][x]=;
}
if(n==){printf("%d 1\n",v[]);continue;}//
memset(dp,-,sizeof dp);memset(f,,sizeof f);
ans=-;prn=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(b[i][j])
{
int D=((<<(i-))|(<<(j-)));//注意括号!
ll w=dfs(D,i,j)+v[i]*v[j]+v[i]+v[j];
if(w>ans)ans=w,prn=f[D][i][j];
else if(w==ans)prn+=f[D][i][j];
}
printf("%I64d %I64d\n",prn?ans:,prn>>);//
}
return ;
}

改成刷表就可A了。注意初始化一遍,然后开始dp,而不是一边初始化一边dp很多次。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=,Lm=(<<)+;
int T,n,m,c[N],lm;
ll dp[Lm][N][N],f[Lm][N][N],ans,prn;
bool b[N][N];
int main()
{
scanf("%d",&T);
while(T--)
{
memset(b,,sizeof b);
scanf("%d%d",&n,&m);lm=(<<n)-;
for(int i=;i<=n;i++)scanf("%d",&c[i]);
int x,y;
while(m--)
{
scanf("%d%d",&x,&y);
b[x][y]=b[y][x]=;
}
if(n==){printf("%d 1\n",c[]);continue;}
memset(dp,-,sizeof dp);memset(f,,sizeof f);
for(int u=;u<=n;u++) for(int v=;v<=n;v++) if(b[u][v])
{
int s=((<<(u-))|(<<(v-)));
dp[s][u][v]=c[u]+c[v]+c[u]*c[v];
f[s][u][v]=;
}
for(int s=;s<=lm;s++)
for(int i=;i<=n;i++) if(s&(<<(i-)))
for(int j=;j<=n;j++) if(dp[s][i][j]!=-)
for(int k=;k<=n;k++) if(b[i][k]&&!(s&(<<(k-))))
{
int d=(s|(<<(k-)));
ll w=dp[s][i][j]+c[k]+c[i]*c[k]+(b[j][k]?c[i]*c[j]*c[k]:);
if(dp[d][k][i]<w)
{
dp[d][k][i]=w;
f[d][k][i]=f[s][i][j];
}
else if(dp[d][k][i]==w)
f[d][k][i]+=f[s][i][j];
}
ans=-;prn=;//因为有"prn?"
for(int i=;i<=n;i++) for(int j=;j<=n;j++) if(dp[lm][i][j]!=-)
if(dp[lm][i][j]>ans)ans=dp[lm][i][j],prn=f[lm][i][j];
else if(dp[lm][i][j]==ans)prn+=f[lm][i][j];
printf("%I64d %I64d\n",prn?ans:,prn>>);
}
return ;
}

poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)的更多相关文章

  1. poj 2288 Islands and Bridges ——状压DP

    题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...

  2. poj 2288 Islands and Bridges_状态压缩dp_哈密尔顿回路问题

    题目链接 题目描述:哈密尔顿路问题.n个点,每一个点有权值,设哈密尔顿路为 C1C2...Cn,Ci的权值为Vi,一条哈密尔顿路的值分为三部分计算: 1.每一个点的权值之和 2.对于图中的每一条CiC ...

  3. [poj2288] Islands and Bridges (状压dp)

    Description Given a map of islands and bridges that connect these islands, a Hamilton path, as we al ...

  4. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

  5. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  6. POJ 2411 Mondriaan's Dream ——状压DP 插头DP

    [题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...

  7. 【POJ 2923】Relocation(状压DP+DP)

    题意是给你n个物品,每次两辆车运,容量分别是c1,c2,求最少运送次数.好像不是很好想,我看了网上的题解才做出来.先用状压DP计算i状态下,第一辆可以运送的重量,用该状态的重量总和-第一辆可以运送的, ...

  8. POJ 1185 炮兵阵地 (状压DP)

    题目链接 题意 : 中文题不详述. 思路 :状压DP,1表示该位置放炮弹,0表示不放.dp[i][j][k],代表第 i 行的状态为k时第i-1行的状态为 j 时放置的最大炮弹数.只是注意判断的时候不 ...

  9. 动态规划晋级——POJ 3254 Corn Fields【状压DP】

    转载请注明出处:http://blog.csdn.net/a1dark 分析:刚开始学状压DP比较困难.多看看就发现其实也没有想象中那么难.这道题由于列数较小.所以将行压缩成二进制来看.首先处理第一行 ...

随机推荐

  1. Appium环境安装步骤 + 代码验证环境是否成功

    1.安装Microsoft .NET Framework 4.5 检测本机已安装的程序中,是否已经安装Microsoft .NET Framework 4.5及以上的版本. 如下图所示:   如果没有 ...

  2. css 渐变背景

    background: linear-gradient(left,#fa7f6d, #fc5e7f); left: 从左边开始

  3. mac下企业邮件不能发送的问题

    1,选用服务器:smtp.example.qq.com     使用ssl      用密码      端口:465

  4. linux命令行实用快捷键

    打开一个命令行窗口:ctrl+alt+t 在已有的命令行窗口上开启一个新的tab:ctrl+shift+t

  5. HZOI20190823模拟31题解

    题面:https://www.cnblogs.com/Juve/articles/11425141.html math:仔细看看其实是个水题 #include<iostream> #inc ...

  6. 转:Linux--进程间通信(信号量,共享内存)

    源地址:http://www.cnblogs.com/forstudy/archive/2012/03/26/2413724.html Linux--进程间通信(信号量,共享内存)(转)   一. 信 ...

  7. 学习mysql数据库

    1.数据库是怎么回事 数据库是存储数据的永久空间,通过一种特殊的方式存储到硬盘中 数据库分为关系型数据库和非关系型数据库 mysql查看数据的方式为:结构化查询语言(SQL语句) 访问mysql数据库 ...

  8. 左神算法书籍《程序员代码面试指南》——2_02在单链表和双链表中删除倒数第k个字节

    [题目]分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点.[要求]如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).[题解]从头遍历链表, ...

  9. hibernate4注解字段为mysql的text

    文章的正文detail就需要设置为text 在getter方法上添加注解 @Lob @Basic(fetch = FetchType.LAZY) @Type(type = "text&quo ...

  10. SpringCloud是如何运行的?

    SpringCloud是基于SpringBoot这一高度自动化的应用开发框架,将各类业界比较知名的.得到过实践反馈的开元服务治理相关的技术框架进行优化整合的框架,是一种开发方式的优化和组合,,是一组框 ...