hdu 5691 Sitting in Line 状压dp
题目链接:
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的更多相关文章
- hdu 5691 Sitting in line 状压动归
在本题中,n<=16n<=16n<=16, 不难想到可以将所选数字的编号进行状态压缩. 定义状态 dp[S][j]dp[S][j]dp[S][j],其中 SSS 代表当前所选出的所有 ...
- hdu 5691 Sitting in Line
传送门 Sitting in Line Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/O ...
- HDU 6149 Valley Numer II 状压DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚 ...
- HDU 1074 Doing Homework【状压DP】
Doing Homework Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- HDU 1074 Doing Homework(状压DP)
第一次写博客ORZ…… http://acm.split.hdu.edu.cn/showproblem.php?pid=1074 http://acm.hdu.edu.cn/showproblem.p ...
- 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 ...
- HDU 4906 Our happy ending (状压DP)
HDU 4906 Our happy ending pid=4906" style="">题目链接 题意:给定n个数字,每一个数字能够是0-l,要选当中一些数字.然 ...
- HDU 1074 Doing Homework (状压dp)
题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...
随机推荐
- Oracle中rownum的用法
rownum是Oracle对查询结果进行顺序编号,第一行分配1,第二行2,以此类推.rownum不能以任何表的名称作为前缀. rownum这个伪字段可以用于控制返回的记录行数. 例如表:student ...
- webform网站相关数据控件和其他
一.asp:Repeater <div class="bd"> <ul> <asp:Repeater ID="rept_slide" ...
- IE9 以下版本浏览器兼容HTML5的方法,使用百度静态资源的html5shiv包
<!--[if lt IE9]> <script src="http://apps.bdimg.com/libs/html5shiv/3.7/html5shiv.min.j ...
- sqoop的codegen工具
一.codegen工具的使用 sqoop codegen --connect jdbc:mysql://localhost:3306/test --username root --password 1 ...
- Android Socket通信
1.TCP: xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: ...
- redis安装与php扩展
redis安装:就是一个解压缩的过程 注意先运行:redis-server.exe,在运行redis-cli.exe. php扩展redis. 以上是如何选择相应的文件. 在把文件放在php/ext下 ...
- 金山词霸每日一句开放平台 .NET demo
先附上地址:http://open.iciba.com/?c=api 小金山提供了2种获取数据的方式 1. 通过填入自己的网站名称.网址.邮箱地址 来生成一段javascript脚本,直接将生成的代码 ...
- PHPStorm配置支持友好的Laravel代码自动提示
在项目的composer.json "barryvdh/laravel-ide-helper":"dev-master" 项目config/app.php Ba ...
- hdu 5311 Hidden String
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5311 Hidden String Description Today is the 1st anniv ...
- android开发系列之消息机制
最近接触到一个比较有挑战性的项目,我发现里面使用大量的消息机制,现在这篇博客我想具体分析一下:android里面的消息到底是什么东西,消息机制到底有什么好处呢? 其实说到android消息机制,我们可 ...