Sitting in Line

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

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

解题思路:状态压缩。用dp[i][j]表示选择i状态所表示的数时,以第j个数为结尾时的最大和。转移方程: dp[i|(1<<k)][k] = max(dp[i|(1<<k)][k], dp[i][j] + a[i]*a[j])。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<string>
#include<iostream>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
using namespace std;
typedef long long LL;
#define mid (L+R)/2
#define lson rt*2,L,mid
#define rson rt*2+1,mid+1,R
#pragma comment(linker, "/STACK:102400000,102400000")
const int maxn = 1e5+300;
const LL INF = 1000000000000;
typedef long long LL;
typedef unsigned long long ULL;
int a[30], p[30];
int choice[maxn];
LL dp[maxn][30];
int cal(int x){
int ret = 0;
while(x){
if(x&1)
ret++;
x = x>>1;
}
return ret;
}
int main(){
int T, n, cas = 0;
scanf("%d",&T);
//预处理出来数字i二进制中有多少个1,因为在有定位置的数时,需要保证前面有那么多个1
for(int i = 0; i <= (1<<16); i++){
choice[i] = cal(i);
}
while(T--){
scanf("%d",&n);
for(int i = 0; i < n; i++){
scanf("%d%d",&a[i],&p[i]);
}
for(int i = 0; i <= (1<<n); i++){
for(int j = 0; j <= n; j++){
dp[i][j] = -INF;
}
}
a[n] = 0; //只是为了初始化
dp[0][n] = 0; //只是为了初始化
for(int i = 0; i < (1<<n); i++){
for(int j = 0; j <= n; j++){
if(dp[i][j]!= -INF){
for(int k = 0; k < n; k++){
if((i&(1<<k)) == 0&&(p[k] == -1 || p[k] == choice[i])){
dp[i|(1<<k)][k] = max(dp[i|(1<<k)][k],dp[i][j] + a[j]*a[k]);
}
}
}
}
}
LL ans = -INF;
for(int i = 0; i < n; i++){
ans = max(ans, dp[(1<<n)-1][i]);
}
printf("Case #%d:\n",++cas);
printf("%lld\n",ans);
}
return 0;
}

  

HDU 5691 ——Sitting in Line——————【状压动规】的更多相关文章

  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 状压dp

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

  3. hdu 5691 Sitting in Line

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

  4. 解题报告 『[USACO08NOV]Mixed Up Cows(状压动规)』

    原题地址 观察数据范围:4 ≤ N ≤ 16. 很明显,这是一道状压DP. 定义:dp[i][j]表示队尾为奶牛i,当前含奶牛的状态为j,共有多少组符合条件的队伍. 代码实现如下: #include ...

  5. [SCOI2008]奖励关 - 状压动规 - 概率与期望

    Description 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝 ...

  6. BZOJ 1725: [Usaco2006 Nov]Corn Fields牧场的安排 状压动归

    Description Farmer John新买了一块长方形的牧场,这块牧场被划分成M列N行(1<=M<=12; 1<=N<=12),每一格都是一块正方形的土地.FJ打算在牧 ...

  7. HDU 3605 Escape 最大流+状压

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3605 Escape Time Limit: 2000/1000 MS (Java/Others)    ...

  8. HDU 5025 (BFS+记忆化状压搜索)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5025 题目大意: 迷宫中孙悟空救唐僧,可以走回头路.必须收集完钥匙,且必须按顺序收集.迷宫中还有蛇, ...

  9. HDU 6149 Valley Numer II 状压DP

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

随机推荐

  1. jquery库与其他库冲突的问题解决-jquery.noConflict()

    在使用jQuery开发的时候,可能还会使用到其他的JS库,比如Prototype,但多库共存时可能会发生冲突:若是发生冲突后,可以通过以下几种方案进行解决: 一. jQuery库在其他库之前导入,直接 ...

  2. Page.FindControl(string id) 与母版页结合后发现的一个问题

    MSDN上解释Page.FindControl(string id)方法用于查找指定ID的控件.例如: <asp:TextBox id="Email" runat=" ...

  3. 初学python - 字典

    字符串转为字典 import astline=input()linedict=ast.literal_eval(line) 遍历字典 for key in linedict: value=linedi ...

  4. 微信小程序遇到的问题与解决

    1.微信开发工具报错 400 (Bad Request) 解决方法: 注:因为开发工具升级 content-type的写法变了 如下代码: header:{     "Content-Typ ...

  5. react-route简明学习

  6. 恢复 MSSQL bak 文件扩展名数据(上)

    恢复 MSSQL bak 文件扩展名数据 一.概念: Microsoft SQL Server是由美国微软公司所推出的关系数据库解决方案,最新的版本是SQL Server 2016,已经在2016年6 ...

  7. 模块time, datetime的用法

    一. time  time库提供了各种操作时间的方法   1. time.asctime([tuple]):将一个时间元组转换成一个可读的24个时间字符串. >>> time.asc ...

  8. ThreadFactory类的使用

    之前创建线程的话,基本上是使用new Thread(),或者是将任务提交到线程池执行.今天看了一下洁城浩的<图解java多线程设计模式>突然看到还可以使用ThreadFactory来创建一 ...

  9. python使用easyinstall安装xlrd、xlwt、pandas等功能模块的方法

    在日常工作中,使用Python时经常要引入一些集成好的第三方功能模块,如读写excel的xlrd和xlwt模块,以及数据分析常用的pandas模块等. 原生的python并不含这些模块,在使用这些功能 ...

  10. 单臂vlan路由实现过程

    单臂路由拓扑图如下: 实现步骤如下: 1)pc的ip自己配置. 2)在交换机的各个端上划分好vlan 下联口:vlan 10     port g1/0/2 vlan 20   port g1/0/3 ...