传送门

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
2016"百度之星" - 初赛(Astar Round2A)
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
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <vector>
  7
  8 using namespace std;
  9
 10 #define N 19
 11 #define ll long long
 12
 13 ll ma;
 14 ll a[N];
 15 int p[N];
 16 int have[N];
 17 int n;
 18 ll dp[ (1 << 17) ][N];
 19 int tot;
 20 ll inf;
 21 vector<int> G[N];
 22
 23 int cal(int x)
 24 {
 25     int ret = 0;
 26     while(x){
 27         ret += (x & 1);
 28         x /= 2;
 29     }
 30     return ret;
 31 }
 32
 33 void ini()
 34 {
 35     int o;
 36     for(o = 0;o < n;o++){
 37         G[o].clear();
 38     }
 39     for(o = 0;o < tot;o++){
 40         G[ cal(o) ].push_back(o);
 41     }
 42 }
 43
 44 int main()
 45 {
 46
 47     int T;
 48     //freopen("in.txt","r",stdin);
 49     //freopen("out.txt","w",stdout);
 50     scanf("%d",&T);
 51     for(int ccnt = 1;ccnt <= T;ccnt++){
 52         scanf("%d",&n);
 53         inf = (1LL << 60);
 54         ma = -inf;
 55         tot = (1 << n);
 56         ini();
 57         int i;
 58         memset(have,-1,sizeof(have));
 59         for(i = 0;i < n;i++){
 60             scanf("%I64d%d",&a[i],&p[i]);
 61             if(p[i] != -1){
 62                 have[ p[i] ] = i;
 63             }
 64         }
 65         int o,nt;
 66         for(o = 0;o < tot;o++){
 67             for(i = 0;i < n;i++){
 68                 dp[o][i] = -inf;
 69             }
 70         }
 71         for(i = 0;i < n;i++){
 72             if(p[i] == 0 || p[i] == -1){    //放在第一个
 73                 dp[ (1 << i) ][i] = 0;
 74             }
 75         }
 76
 77         /*
 78         for(i = 0;i < n;i++){
 79             for(int j = 0;j < G[i].size();j++){
 80                 printf(" i =%d j = %d g= %d\n",i,j,G[i][j]);
 81             }
 82         }*/
 83         for(i = 1;i < n;i++){      //放第i位
 84             int sz = G[i].size();
 85             for(int j = 0;j < sz;j++){  //遍历含有i个1的所有数
 86                 o = G[i][j];
 87                 for(int k = 0;k < n;k++)    //把第k个数放在第i位
 88                 {
 89
 90                     if( o & (1 << k) ) continue;    //k已经放了
 91                     if( p[k] != -1 && p[k] != i ) continue; //k被固定了
 92                     if( have[i] != -1 && have[i] != k ) continue;   //位置i被固定了
 93                     nt = o | (1 << k);
 94                     //printf(" i = %d o = %d k = %d nt = %d\n",i,o,k,nt);
 95                     for(int pr = 0;pr < n;pr++){
 96                         if( (o & (1 << pr ) ) == 0) continue;    //pr不在o里
 97                         if( dp[o][pr] == -inf ) continue;
 98                         //printf(" i = %d o = %d k = %d nt = %d pr = %d\n",i,o,k,nt,pr);
 99                         dp[nt][k] = max(dp[nt][k],dp[o][pr] + a[pr] * a[k]);
100                     }
101                 }
102             }
103         }
104         /*
105         for(o = 0;o < tot;o++){
106             for(i = 0;i < n;i++){
107                 printf(" o = %d i = %d dp = %I64d\n",o,i,dp[o][i]);
108             }
109         }*/
110         for(i = 0;i < n;i++){
111             ma = max(ma,dp[tot - 1][i]);
112         }
113         printf("Case #%d:\n",ccnt);
114         printf("%I64d\n",ma);
115     }
116
117     return 0;
118 }

转载于:https://www.cnblogs.com/njczy2010/p/5515788.html

hdu 5691 Sitting in Line相关推荐

  1. HDU 5691 Sitting in Line 状压dp

    Sitting in Line 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5691 Description 度度熊是他同时代中最伟大的数学家,一切 ...

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

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

  3. 2016百度之星 - 初赛(Astar Round2A)解题报告

    此文章可以使用目录功能哟↑(点击上方[+]) 有点智商捉急,第一题卡了好久,看来不服老,不服笨是不行的了...以下是本人目前的题解,有什么疑问欢迎提出 链接→2016"百度之星" ...

  4. 2016百度之星总结帖

    2016百度之星总结帖 测试赛 选的2015资格赛的部分题目,第二题字符串处理,第三题map计数 1001 大搬家 f f (x) = x 两次置换后回到原位 dp a->b && ...

  5. 【HDU 3400】Line belt(三分法)

    题目链接 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3400 题意 有两条传送带AB和CD,移动速度分别为p,q. 除了传送带的其他区域移动速度为r ...

  6. HDU 6631 line symmetric(枚举)

    首先能想到的是至少有一对相邻点或者中间间隔一个点的点对满足轴对称,那么接下来只需要枚举剩下的点对是否满足至多移动一个点可以满足要求. 第一种情况,对于所有点对都满足要求,那么Yes. 第二种情况,有一 ...

  7. HDU 3400 Line belt (三分)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3400 题意:给定两条线段AB,CD,在这两条线段上速度分别为P,Q,在其他地方速度为R,让求A 到 D ...

  8. HDU 3400 Line belt【三分法】

    题意: 有两条线段,在其中一条线段上移动的速度为 v1,在另一条线上速度为v2, 在其他地方移动速度为 r,问从其中一条线段的一个端点移动到另一个线段 的一个端点的最少时间. 分析: 在其中一条线段上 ...

  9. 暑期集训3:几何基础 练习题G: HDU - 1052

    2018学校暑期集训第三天--几何基础 练习题G  --   HDU - 1052   (昨天加练题) Tian Ji -- The Horse Racing Here is a famous sto ...

最新文章

  1. openssl 非对称加密 RSA 加密解密以及签名验证签名
  2. Android用户界面设计:框架布局
  3. of介词短语作定语_如何区分介词短语作状语还是作定语
  4. 借助Web技术,桌面用户界面将保持活跃
  5. 数字后端基本概念-合集
  6. 牛客网 二叉搜索树与双向链表
  7. [转载] Python数据分析:python与numpy效率对比
  8. Tomcat日志乱码问题解决方法
  9. Java数据持久层框架
  10. win10/win11掉驱动问题
  11. ${pram.name}
  12. es中的keyword相关功能
  13. jQuery的选择器大全
  14. 在精不在多,3 分钟看 3 个 JS 小把戏
  15. MCAL中PORT配置
  16. 大学C语言系统作业,南昌大学作业答疑系统c语言答案
  17. 线程经典实例——吃苹果问题
  18. unity3d中animator和animation k动画注意点和问题 无法播放等等
  19. 功利性地去多读书(一年300本书)
  20. 使用ThreeJs从零开始构建3D智能仓库——第二章(创建地面与门窗)

热门文章

  1. python3安装scrapy及使用方法(爬虫框架)
  2. 深入了解Debug和Release的区别
  3. vue小demo易错点总结
  4. 《专门替中国人写的英语语法》(四)
  5. 【Android】完善Android学习(二:API 2.3.4)
  6. 大数据解密之你的同事都跳槽到了哪些公司
  7. CANOpen服务数据对象报文
  8. CANOpen定时器
  9. java 可选参数_超干货详解:kotlin(4) java转kotlin潜规则
  10. 没想到,我都来阿里5年了!