题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5691

题解:

和tsp用的状压差不多,就是固定了一些访问顺序。

dp[i][j]表示前cnt个点中布满状态i且最后一个为j的状态的最大乘积和。

则有dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+a[j]*a[k])。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn = ;
const int INF = 2e9;
int dp[ << ][];
int cnt[ << ];
int a[maxn], p[maxn],f[maxn];
int n; void pre() {
for (int i = ; i < ( << ); i++) {
cnt[i] = ;
for (int j = ; j < ; j++) {
if (i&( << j)) cnt[i]++;
}
}
} void init() {
for (int i = ; i < ( << n); i++) {
for (int j = ; j <= n; j++) {
dp[i][j] = -INF;
}
}
memset(f, -, sizeof(f));
} int main() {
pre();
int tc,kase=;
scanf("%d", &tc);
while (tc--) {
scanf("%d", &n);
init();
for (int i = ; i < n; i++) {
scanf("%d%d", a + i, p + i);
if (p[i] != -) f[p[i]] = i;
}
a[n] = ; p[n] = n;
dp[][n] = ;
for (int i = ; i < ( << n); i++) {
int sum = cnt[i];
for (int j = ; j <= n; j++) {
if ((i&( << j)) == &&j!=n) continue;
//被限制的点:
if (f[sum] != -) {
if ((i&( << f[sum])) == ) {
dp[i | ( << f[sum])][f[sum]] =
max(dp[i | ( << f[sum])][f[sum]], dp[i][j]+a[j]*a[f[sum]]);
}
}
else {
//可以自由移动的点
for (int k = ; k < n; k++) {
if (i&( << k)) continue;
if (p[k] ==-) {
dp[i | ( << k)][k] = max(dp[i | ( << k)][k], dp[i][j] + a[j] * a[k]);
}
}
}
}
}
int ans = -INF;
for (int j = ; j < n; j++) ans = max(ans, dp[( << n) - ][j]);
printf("Case #%d:\n", ++kase);
printf("%d\n", ans);
}
return ;
}

再一发:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=0x3f3f3f3f;
const LL INFL=10000000000000000LL;
const double eps=1e-; const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn=; LL dp[<<maxn][maxn];
LL arr[maxn];
int pos[maxn],mp[maxn];
int sumv[<<maxn];
int n; void pre(){
clr(sumv,);
for(int i=;i<(<<maxn);i++){
for(int j=;j<maxn;j++){
if(i&(<<j)){
sumv[i]++;
}
}
}
} void init(){
clr(mp,-);
} int main() {
pre();
int tc,kase=;
scf("%d",&tc);
while(tc--){
scf("%d",&n);
init();
rep(i,,n){
scf("%lld%d",&arr[i],&pos[i]);
if(pos[i]>=) mp[pos[i]]=i;
} rep(i,,(<<maxn)) rep(j,,maxn) dp[i][j]=-INFL;
if(mp[]>=){
dp[<<mp[]][mp[]]=;
}else{
for(int i=;i<n;i++){
if(pos[i]>=) continue;
dp[<<i][i]=;
}
} rep(i,,(<<n)){
rep(j,,n){
if(!(i&(<<j))) continue;
if(mp[sumv[i]-]>=&&mp[sumv[i]-]!=j) continue;
rep(k,,n){
if(k==j||!(i&(<<k))) continue;
if(mp[sumv[i^(<<j)]-]>=&&mp[sumv[i^(<<j)]-]!=k) continue;
dp[i][j]=max(dp[i][j],dp[i^(<<j)][k]+arr[k]*arr[j]);
}
}
} LL ans=-INFL;
rep(i,,n) ans=max(ans,dp[(<<n)-][i]);
prf("Case #%d:\n",++kase);
prf("%lld\n",ans); }
return ;
} //end-----------------------------------------------------------------------

hdu 5691 Sitting in Line 状压dp的更多相关文章

  1. hdu 5691 Sitting in line 状压动归

    在本题中,n<=16n<=16n<=16, 不难想到可以将所选数字的编号进行状态压缩. 定义状态 dp[S][j]dp[S][j]dp[S][j],其中 SSS 代表当前所选出的所有 ...

  2. hdu 5691 Sitting in Line

    传送门 Sitting in Line Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/O ...

  3. HDU 6149 Valley Numer II 状压DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚 ...

  4. HDU 1074 Doing Homework【状压DP】

    Doing Homework Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he ...

  5. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  6. HDU 1074 Doing Homework(状压DP)

    第一次写博客ORZ…… http://acm.split.hdu.edu.cn/showproblem.php?pid=1074 http://acm.hdu.edu.cn/showproblem.p ...

  7. HDU - 4284 Travel(floyd+状压dp)

    Travel PP loves travel. Her dream is to travel around country A which consists of N cities and M roa ...

  8. HDU 4906 Our happy ending (状压DP)

    HDU 4906 Our happy ending pid=4906" style="">题目链接 题意:给定n个数字,每一个数字能够是0-l,要选当中一些数字.然 ...

  9. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...

随机推荐

  1. WWDC————苹果全球开发者大会

    WWDC:Apple Worldwide Developers Conference(苹果全球开发者)的简称,每年定期由苹果公司(Apple Inc.)在美国举办.大会主要的目的是让苹果公司向研发者们 ...

  2. WordPress 撰写文章页面显示所有标签

    WordPress 撰写文章时,点击"从常用标签中选择"只显示45个常用的标签,很多情况下还需手工再次输入标签,这样的限制感觉很不方便,通过下面的方法可以解除这个限制,显示全部标签 ...

  3. Windows程序设计之Hello,Windows 98程序的声音调试记录

    最近在Window程序设计第五版,刚看到第三章,第三章中有一个程序调用了一个多媒体对象库winmm.lib库,由于该库不再默认项目中,如果不手动添加,编译时会提示错误而无法运行,但是书上用的是Visu ...

  4. 基于.NET的WebService的实现和WCF的实现

    1.新建一个MVC web项目. 2.点击项目,[右键]→[添加]→[新建项] 3.点击[Web]→[Web服务] 4.恭喜,Web Service已经新建成功,里面的方法就可以参考着根据自己的需要进 ...

  5. 共享内存shared pool (4):Library cache 转储文件

    上一篇blog只是从概念上理解Library cache,本篇则是将Library cache从内存中dump出来,看看其结构. 基本命令 ALTER SESSION SET EVENTS 'imme ...

  6. python 关于 ImportError: No module named 的问题

    转载自:http://my.oschina.net/leejun2005/blog/109679 今天在 centos 下安装 python setup.py install 时报错:ImportEr ...

  7. Python核心编程--学习笔记--1--Python简介

    本章介绍了Python的背景知识,包括什么是Python.Python的起源以及Python的一些关键特性. 1 什么是Python Python是一门优雅而健壮的编程语言,它继承了传统编译语言的强大 ...

  8. hdu 5327 Olympiad

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5327 Olympiad Description You are one of the competit ...

  9. 【linux命令系列】熟练运用每一个光标移动到最前和最后

    ctrl+e?a和e      ahead 和 end 看一个真正的专家操作命令行绝对是一种很好的体验-光标在单词之间来回穿梭,命令行不同的滚动.在这里强烈建立适应GUI节目的开发者尝试一下在提示符下 ...

  10. SQL Server数据库学习笔记-设计表时应该考虑的因素

    设计数据库其实就是设计数据库中的表.到底要注意些什么才能够设计好一个数据库呢?一个宗旨,8个建议. 一个宗旨“尽量少的表,每个表中尽量少的列,合理的表结构”. 8个建议: 第一个,首先要考虑的是咱们这 ...