传送门

Sitting in Line

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 293    Accepted Submission(s): 143

Problem Description
度度熊是他同时代中最伟大的数学家,一切数字都要听命于他。现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了。游戏的规则十分简单,参与游戏的N个整数将会做成一排,他们将通过不断交换自己的位置,最终达到所有相邻两数乘积的和最大的目的,参与游戏的数字有整数也有负数。度度熊为了在他的数字仆人面前展现他的权威,他规定某些数字只能在坐固定的位置上,没有被度度熊限制的数字则可以自由地交换位置。
 
Input
第一行一个整数T,表示T组数据。
每组测试数据将以如下格式从标准输入读入:

N

a1p1

a2p2

:

aNPN

第一行,整数 N(1≤N≤16),代表参与游戏的整数的个数。

从第二行到第 (N+1) 行,每行两个整数,ai(−10000≤ai≤10000)、pi(pi=−1 或 0≤pi<N),以空格分割。ai代表参与游戏的数字的值,pi代表度度熊为该数字指定的位置,如果pi=−1,代表该数字的位置不被限制。度度熊保证不会为两个数字指定相同的位置。

 
Output
第一行输出:"Case #i:"。i代表第i组测试数据。

第二行输出数字重新排列后最大的所有相邻两数乘积的和,即max{a1⋅a2+a2⋅a3+......+aN−1⋅aN}。

 
Sample Input
2
6
-1 0
2 1
-3 2
4 3
-5 4
6 5
5
40 -1
50 -1
30 -1
20 -1
10 -1
 
Sample Output
Case #1:
-70
Case #2:
4600
 
Source
 
Recommend
wange2014   |   We have carefully selected several similar problems for you:  5695 5694 5693 5692 5690 
 
 
 
题意:
数组中有些元素位置被固定了,有些可以换位置,求
max{a1⋅a2+a2⋅a3+......+aN−1⋅aN}
 
题解:
真不容易,田神给我说了思路,还编了好久2333

状压dp,比赛时没时间思考了。。。

其实,观察所要求的max{a1⋅a2+a2⋅a3+......+aN−1⋅aN}

可以发现,你发完前 i - 1 位 元素后,准备放第 i 位 元素时,当前的 max 只 与 a[i-1] 有关了 (a[i - 1] * a[i]),所以可以用状压dp

定义 dp[o][i] 为放完第i位(以a[i] 为结尾),状态 o 时的max

遍历的顺序见代码

17232841 2016-05-21 22:22:30 Accepted 5691 1294MS 11724K 2946B G++ czy
 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std; #define N 19
#define ll long long ll ma;
ll a[N];
int p[N];
int have[N];
int n;
ll dp[ ( << ) ][N];
int tot;
ll inf;
vector<int> G[N]; int cal(int x)
{
int ret = ;
while(x){
ret += (x & );
x /= ;
}
return ret;
} void ini()
{
int o;
for(o = ;o < n;o++){
G[o].clear();
}
for(o = ;o < tot;o++){
G[ cal(o) ].push_back(o);
}
} int main()
{ int T;
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&T);
for(int ccnt = ;ccnt <= T;ccnt++){
scanf("%d",&n);
inf = (1LL << );
ma = -inf;
tot = ( << n);
ini();
int i;
memset(have,-,sizeof(have));
for(i = ;i < n;i++){
scanf("%I64d%d",&a[i],&p[i]);
if(p[i] != -){
have[ p[i] ] = i;
}
}
int o,nt;
for(o = ;o < tot;o++){
for(i = ;i < n;i++){
dp[o][i] = -inf;
}
}
for(i = ;i < n;i++){
if(p[i] == || p[i] == -){ //放在第一个
dp[ ( << i) ][i] = ;
}
} /*
for(i = 0;i < n;i++){
for(int j = 0;j < G[i].size();j++){
printf(" i =%d j = %d g= %d\n",i,j,G[i][j]);
}
}*/
for(i = ;i < n;i++){ //放第i位
int sz = G[i].size();
for(int j = ;j < sz;j++){ //遍历含有i个1的所有数
o = G[i][j];
for(int k = ;k < n;k++) //把第k个数放在第i位
{ if( o & ( << k) ) continue; //k已经放了
if( p[k] != - && p[k] != i ) continue; //k被固定了
if( have[i] != - && have[i] != k ) continue; //位置i被固定了
nt = o | ( << k);
//printf(" i = %d o = %d k = %d nt = %d\n",i,o,k,nt);
for(int pr = ;pr < n;pr++){
if( (o & ( << pr ) ) == ) continue; //pr不在o里
if( dp[o][pr] == -inf ) continue;
//printf(" i = %d o = %d k = %d nt = %d pr = %d\n",i,o,k,nt,pr);
dp[nt][k] = max(dp[nt][k],dp[o][pr] + a[pr] * a[k]);
}
}
}
}
/*
for(o = 0;o < tot;o++){
for(i = 0;i < n;i++){
printf(" o = %d i = %d dp = %I64d\n",o,i,dp[o][i]);
}
}*/
for(i = ;i < n;i++){
ma = max(ma,dp[tot - ][i]);
}
printf("Case #%d:\n",ccnt);
printf("%I64d\n",ma);
} return ;
}

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

  1. HDU 5691 ——Sitting in Line——————【状压动规】

    Sitting in Line Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Other ...

  2. hdu 5691 Sitting in line 状压动归

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

  3. hdu 5691 Sitting in Line 状压dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5691 题解: 和tsp用的状压差不多,就是固定了一些访问顺序. dp[i][j]表示前cnt个点中布 ...

  4. 2016"百度之星" - 初赛(Astar Round2A)1002 / HDU 5691 状态压缩DP

    Sitting in Line Problem Description   度度熊是他同时代中最伟大的数学家,一切数字都要听命于他.现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了.游戏的规则十 ...

  5. HDU5691 Sitting in Line【状压DP】

    HDU5691 Sitting in Line 题意: 给出\(n\)个数字,有些数字的位置固定了,现在要求把所有没固定的数字放在一个位置,使得任意相邻两个位置的数字的相乘的和最大 题解: \(n\) ...

  6. hdu 5691(状压DP) Sitting in Line

    题目http://acm.hdu.edu.cn/showproblem.php?pid=5691 状态DP,dp[i][j],i 表示的是一种状态,这个状态指的是当前这个数取或不取,j表示的是以第j个 ...

  7. HDU 3623 Best Cow Line, Gold(模拟,注意思路,简单)

    题目 POJ 3617 和 这道题题目一样,只是范围稍稍再小一点. //模拟试试 #include<stdio.h> #include<string.h> #include&l ...

  8. hdu5691 Sitting in Line(状压dp)

    1 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...

  9. 2016百度之星 初赛2A ABEF

    只做了1001 1002 1005 1006.剩下2题可能以后补? http://acm.hdu.edu.cn/search.php?field=problem&key=2016%22%B0% ...

随机推荐

  1. Linux命令权限 用户权限 组权限 文件、目录权限

    Linux命令的格式是: 命令+选项+参数 命令是必须存在的,选项和参数可以不必存在,不写的情况是有默认的参数 Linux 一切皆文件 对于文件而言,只需要对文件进行读写就可以实现对文件内容内容的增删 ...

  2. PAT (Basic Level) Practise (中文)- 1024. 科学计数法 (20)

    PAT (Basic Level) Practise (中文)- 1024. 科学计数法 (20) http://www.patest.cn/contests/pat-b-practise/1024 ...

  3. iPhone Scrollbars with iScroll

    Since we've had web browsers and JavaScript, we've been intent on replacing native browser functiona ...

  4. HTML5<picture>元素

    HTML5<picture>元素可以设置多张图片 <!DOCTYPE html><html><head><meta http-equiv=&quo ...

  5. 如何让升级时AppleHDA不再折腾

    ---前提--- 1. 你得用 Clover 引导 (......) 2. 开启 kernelcache (开了也能 inject kext,还能patch kext,速度又快,为啥不开) 3. 你的 ...

  6. pip install mysqlclient 报错:error: Microsoft Visual C++ 14.0 is required.

    解决办法: 1. 在网址:https://www.lfd.uci.edu/~gohlke/pythonlibs/  下载对应的whl文件,如我的环境是python3.7.2  windows32位版本 ...

  7. 006 CSS三种引入方式

    CSS三种引入方式 一.三种方式的书写规范 1.行间式 <div style="width: 100px; height: 100px; background-color: red&q ...

  8. 模块导入及使用,关键字,模块搜索路径,python文件的两种用途

    06.05自我总结 一.模块导入及使用 1.模块导入的两种方式 我们拿time模块并使用其中的time功能进行举例 a)第一种 import time print(time.time) import首 ...

  9. Pandas中loc,iloc与直接切片的区别

    最近使用pandas,一直搞不清楚其中几种切片方法的区别,今天专门看了一下. 0. 把Series的行index或Dataframe的列名直接当做属性来索引. 如: s.index_name df.c ...

  10. Python之路-基础数据类型之字典 集合

    字典的定义-dict 字典(dict)是python中唯⼀的⼀个映射类型.他是以{ }括起来的键值对组成,字典是无序的,key是不可修改的.dic = {1:'好',2:'美',3:'啊'} 字典的操 ...