一个不错的题解 : http://blog.csdn.net/accry/article/details/6607703

这是一道状态压缩。每个点有一个值,我们最后要求一个最值sum。sum由三部分组成:①每个点的值②每个点与他相邻的点的乘积③如果存在三个点成环,还要加上这三个点的值的乘积。

状态转移方程为:dp[i][j][k]=max(dp[i,j,k],dp[i'][k][l]+temp) j表示当前点,k表示上一个点,l表示上上一个点。

其中i,i'表示可以走到i点的状态,temp表示这个状态过来需要加的值,它等于value[j]+value[j]*value[k](如果j,k,l成环还要+value[j]*value[k]*value[l]).

当i状态表示只由两个点构成时,dp[i][j][k]=value[j]+value[j]*value[k].

但是此题不止要求最大值,还有求最大值的个数。于是我们开一个way数组,way[i][j][k]表示i状态由当前点i和上一个点k所有个方案数。于是如果dp[i][j][k]=dp[i'][k][l]+temp是way[i][j][k]+=way[i'][k][l],如果是dp[i][j][k]<dp[i'][k][l]+temp时way[i][j][k]=way[i'][k][l].

本来是这样,但是我很蛋疼得想如果在dp的同时去更新最大值和最大个数。于是就导致1个小时不断的wa,不断找反例,不断改,终于过了orz……。

如果要按我那么做,就是不断更新最大值,那么就一定要在第二个循环内……以及一些奇奇怪怪的限制,只能说这是一个神奇的经历,不断读程序理解思想……(其实是因为没有数据)说明我以前太依赖现有数据去调程序了……

var

  dp,way:array[..mm,..,..]of int64;

  f:array[..]of int64;

  map:array[..,..]of boolean;

  j,k,l,n,m,i,state,p,temp,top:longint;

  ans1,ans2:int64;

begin

  readln(p);

  while p<> do begin

    dec(p);

    read(n,m);

    fillchar(f,sizeof(f),);

    for i:= to n do read(f[i]);

    if n= then begin

      writeln(f[],'');

      continue;

    end;

    readln;

    fillchar(map,sizeof(map),false);

    fillchar(way,sizeof(way),);

    fillchar(dp,sizeof(dp),);

    for i:= to m do begin

      read(j,k);

      map[j,k]:=true;

      map[k,j]:=true;

    end;

    top:=<<n-;

    ans1:=-;

    ans2:=;

    for i:= to top do

      for j:= to n do

        if (i and ( << (j-) )<>) then

          for k:= to n do

            if (j<>k) and ((i and ( << (k-) ))<>) and (map[j,k]) then begin

              if i=(<<(j-))+(<<(k-)) then begin

                dp[i,j,k]:=f[j]+f[k]+f[j]*f[k];

                way[i,j,k]:=;

              end

                else begin

                  for l:= to n do

                    if (j<>l) and (l<>k) and (i and ( << (l-))<>)and map[k,l] then begin

                      state:=i-(<<(j-));

                      if dp[state,k,l]=- then continue;

                      temp:=f[j]*f[k]+f[j]+dp[state,k,l];

                      if map[j,l] then inc(temp,f[j]*f[k]*f[l]);

                      if dp[i,j,k]>temp then continue;

                      if dp[i,j,k]=temp then

                        inc(way[i,j,k],way[state,k,l]);

                      if dp[i,j,k]<temp then begin

                        dp[i,j,k]:=temp;

                        way[i,j,k]:=way[state,k,l];

                      end;

                    end;

                end;

              if (i=top) then begin

                    if ans1=dp[i,j,k] then

                      ans2:=ans2+way[i,j,k]

                    else

                      if ans1<dp[i,j,k] then begin

                        ans1:=dp[i,j,k];

                        ans2:=way[i,j,k];

                      end;

                  end;

              end;

   if ans1=- then writeln('0 0')

   else writeln(ans1,' ',ans2 div );

  end;

end.

【以前的空间】poj 2288 Islands and Bridges的更多相关文章

  1. POJ 2288 Islands and Bridges(状压dp)

    http://poj.org/problem?id=2288 题意: 有n个岛屿,每个岛屿有一个权值V,一条哈密顿路径C1,C2,...Cn的值为3部分之和: 第1部分,将路径中每个岛屿的权值累加起来 ...

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

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

  3. poj 2288 Islands and Bridges——状压dp(哈密尔顿回路)

    题目:http://poj.org/problem?id=2288 不知为什么记忆化搜索就是WA得不得了! #include<iostream> #include<cstdio> ...

  4. poj 2288 Islands and Bridges

    题意: 给你一个双向连通图,求 获得权值最大 的 哈密顿通路的 权值 和 这个权值对应的数目: 其中权值计算方法是  列如 ABCD  权值是a+b+c+d+ab+bc+cd 如果 A,B,C  和B ...

  5. POJ 2288 Islands and Bridges (状压DP,变形)

    题意: 给一个无向图,n个点m条边,每个点有点权,要求找到一条哈密顿路径,使得该路径的f(path)值最大.输出f值,若有多条最大f值的路径,输出路径数量. f值由如下3点累加而来: (1)所有点权之 ...

  6. poj 2288 Islands and Bridges (状压dp+Tsp问题)

    这道题千辛万苦啊! 这道题要涉及到当前点和前面两个点,那就设dp[state][i][j]为当前状态为state,当前点为i,前一个点为j 这个状态表示和之前做炮兵那题很像,就是涉及到三个点时,就多设 ...

  7. POJ 2288 Islands and Bridges(状压DP)题解

    题意:n个点,m有向边,w[i]表示i的价值,求价值最大的哈密顿图(只经过所有点一次).价值为:所有点的w之和,加上,每条边的价值 = w[i] * w[j],加上,如果连续的三个点相互连接的价值 = ...

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

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

  9. poj 2280 Islands and Bridges 哈密尔顿路 状压dp

    题目链接 题意 给定一个\(N\)个点的无向图,求一条哈密尔顿路径\(C_1C_2...C_n\),使其\(value\)最大. \(value\)的计算方式如下:\[\begin{aligned}v ...

随机推荐

  1. SQL注入的原理与预防

    1. 什么是SQL注入? SQL注入是常见的网络攻击方式之一,通过SQL语句实现无账号登录,非法获取甚至篡改数据库中的数据. 2. SQL注入的思路 (1)找到SQL注入位置: (2)判断服务器类型和 ...

  2. elasticsearch集群整合elqsticsearch-sql插件

    1.本来整合这个插件是比较简单易操作的,但是由于公司从AWS下载禁掉了,给安装带来一些麻烦, 采用离线安装,先FQ将elasticsearch-sql-5.1.2.0.zip下载下来: ./bin/e ...

  3. Linux 下获取通讯IP

    #!/bin/sh # filename: get_net.sh default_route=$(ip route show) default_interface=$() address=$(ip a ...

  4. 180623-SpringBoot之logback配置文件

    SpringBoot配置logback 项目的日志配置属于比较常见的case了,之前接触和使用的都是Spring结合xml的方式,引入几个依赖,然后写个 logback.xml 配置文件即可,那么在S ...

  5. 安迪的第一个字典 (Andy's First Dictionary,UVa10815)

    题目描述: #include<iostream> #include<string> #include<set> #include<sstream> us ...

  6. [译] JavaScript核心指南(JavaScript Core) 【转】

    本文转自:http://remember2015.info/blog/?p=141#scope-chain 零.索引 对象(An Object) 原型链(A Prototype Chain) 构造函数 ...

  7. Java学习笔记-10.io流

    1.输入流,只能从中读取数据,而不能向其写出数据.输出流,只能想起写入字节数据,而不能从中读取. 2.InputStream的类型有: ByteArrayInputStream 包含一个内存缓冲区,字 ...

  8. v-if或者v-repeat等不起作用

    v-if或者v-for等不起作用 在项目中,有时遇到了v-if或v-for等形式时,页面没起作用.以下可能是出现这些问题的原因: 1.绑定值是接口返回的某个属性值,而这个属性值不存在data()中,这 ...

  9. a2

    Alpha 冲刺报告 队名: 组长:吴晓晖 今天完成了哪些任务: 代码量300+,完成了百度地图API的引入. 展示GitHub当日代码/文档签入记录: 明日计划: 整理下这两个功能,然后补些bug ...

  10. 总结get和post区别

    参考博文: 浅谈HTTP中Get与Post的区别 1. 数据传递方向: Get是向服务器发索取数据的一种请求,Post是向服务器提交数据的一种请求 (都是请求,并不是一个取一个发) Get:①用于获取 ...