E. Double Elimination DP 01枚举状态和倍增思想

题意

参考DOTA2双败赛制,一共有\(2^n\)个队打n轮 其中你有k喜欢的队伍,由你掌控比赛的输赢请问比赛中包含你喜欢的队伍的场次最多有多少场

思路

看数据就很DP,但是比赛的时候不知道怎么搞。其实喜欢队伍与否就是一个01状态,每一场比赛的都会尝生一个胜利队伍和一个失败队伍,把这个胜利和失败队伍去和相邻的胜利和失败的队伍去比就会另外一个胜利和失败的队伍,这样就可以用倍增的思想去定义状态。

我们定状态为\(dp[i][j][x][y]\)从j出发长度为\(2^i\)的比赛队伍产生的胜者队伍是否为关注的队伍,x=1表示是,0表示不是,败者队伍同理那么转移就可以很方便得列举出来。

转移为 \(dp[i-1][j][x1][y1]\)和\(dp[i-1][j+(1<<(i-1))][x2][y2]\)进行比赛,列举他们的状态进行合并,首先是x1和x1比以及y1和y2比 这样关注的队伍的比赛场次为\(dp[i-1][j][x1][y1]+dp[i-1][j+(1<<(i-1))][x2][y2]+int(x1||x2)+int(y1||y2)\)以及还要根据比赛的具体结果看决出败者的时候是否有关注的队伍,有就要加1,一共8种状态,可以画图找一找

这样复杂度就是\(O(2^{17}*17*8*8)\)

本地只要想到把喜欢与否转变为01状态并且有倍增的思想,那么列出状态后进行转移就相对较为简单,初始化的时候需要把所以dp值初始化成一个非常小的数字,防止进行非法转移,刚开始设置成-1 发生了非法转移样例1都过不去QAQ

#include<bits/stdc++.h>
#define pb push_back
#define mkp make_pair
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=(1<<17)+1;
int dp[17][maxn][2][2];
int vis[maxn];
int n,k;
void init(){
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<n);j+=(1<<i)){
for(int x=0;x<2;x++)
for(int y=0;y<2;y++)dp[i][j][x][y]=-maxn;
}
}
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++){
int x;
scanf("%d",&x);
vis[x-1]=1;
}
//memset(dp,-1,sizeof(dp));
init();
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<n);j+=(1<<i)){
if(i==1){
for(int x1=0;x1<2;x1++){
for(int y1=0;y1<2;y1++){
if(vis[j]+vis[j+1]==x1+y1){
dp[i][j][x1][y1]=(vis[j]+vis[j+1])>0?1:0;
}
}
}
}
else {
for(int x1=0;x1<2;x1++){
for(int y1=0;y1<2;y1++){
for(int x2=0;x2<2;x2++){
for(int y2=0;y2<2;y2++){
int num=dp[i-1][j][x1][y1]+dp[i-1][j+(1<<(i-1))][x2][y2];
if(x1||x2)num++;
if(y1||y2)num++;
dp[i][j][x1][y1]=max(dp[i][j][x1][y1],num+((x2+y1)>0?1:0));
dp[i][j][x1][y2]=max(dp[i][j][x1][y2],num+((x2+y2)>0?1:0)); dp[i][j][x2][y1]=max(dp[i][j][x2][y1],num+((x1+y1)>0?1:0));
dp[i][j][x2][y2]=max(dp[i][j][x2][y2],num+((x1+y2)>0?1:0)); dp[i][j][x1][x2]=max(dp[i][j][x1][x2],num+((x2+y1)>0?1:0));
dp[i][j][x1][x2]=max(dp[i][j][x1][x2],num+((x2+y2)>0?1:0)); dp[i][j][x2][x1]=max(dp[i][j][x2][x1],num+((x1+y1)>0?1:0));
dp[i][j][x2][x1]=max(dp[i][j][x2][x1],num+((x1+y2)>0?1:0));
}
}
}
}
}
}
}
int ans=0;
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
ans=max(ans,dp[n][0][i][j]+(i+j>0?1:0));
}
}
printf("%d\n",ans);
return 0;
}

最后感谢qscqesze的题解,感兴趣的可以去B站直接搜这个名字哦

1315E Double Elimination DP 01枚举状态和倍增思想的更多相关文章

  1. 【POJ 2411】【Mondriaans Dream】 状压dp+dfs枚举状态

    题意: 给你一个高为h,宽为w的矩阵,你需要用1*2或者2*1的矩阵填充它 问你能有多少种填充方式 题解: 如果一个1*2的矩形横着放,那么两个位置都用二进制1来表示,如果是竖着放,那么会对下一层造成 ...

  2. poj 2923 状压dp+01背包

    好牛b的思路 题意:一系列物品,用二辆车运送,求运送完所需的最小次数,两辆车必须一起走 解法为状态压缩DP+背包,本题的解题思路是先枚举选择若干个时的状态,总状态量为1<<n,判断这些状态 ...

  3. USACO Money Systems Dp 01背包

    一道经典的Dp..01背包 定义dp[i] 为需要构造的数字为i 的所有方法数 一开始的时候是这么想的 for(i = 1; i <= N; ++i){ for(j = 1; j <= V ...

  4. 树形DP +01背包(HDU 1011)

    题意:有n个房间,有n-1条道路连接着n个房间,每个房间都有若干个野怪和一定的能量值,有m个士兵从1房间入口进去,到达每个房间必须要留下若干士兵杀死所有的野怪,然后其他人继续走,(一个士兵可以杀死20 ...

  5. BZOJ 2748: [HAOI2012]音量调节【二维dp,枚举】

    2748: [HAOI2012]音量调节 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 2010  Solved: 1260[Submit][Statu ...

  6. UVA.10130 SuperSale (DP 01背包)

    UVA.10130 SuperSale (DP 01背包) 题意分析 现在有一家人去超市购物.每个人都有所能携带的重量上限.超市中的每个商品有其相应的价值和重量,并且有规定,每人每种商品最多购买一个. ...

  7. DP大作战—状态压缩dp

    题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...

  8. 状压dp终极篇(状态转移的思想)

    状压dp是将每种状态都压缩成用一个二进制串,然后利用位运算进行操作的dp,而凡是dp都需要进行状态转移 对于简单的dp问题只需要一个二维数组dp[ i ][ j ]就能解决 具体操作为首先把状态压缩为 ...

  9. HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解)

    HDOJ(HDU).3466 Dividing coins ( DP 01背包 无后效性的理解) 题意分析 要先排序,在做01背包,否则不满足无后效性,为什么呢? 等我理解了再补上. 代码总览 #in ...

随机推荐

  1. golang 自定义结构体(与其他语言对象类似)

    /* 结构体变量: 结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正地分配内存, 因此必须在定义结构体并实例化后才能使用结构体的字段. type 类型名 struct { 字段1 字 ...

  2. Vim 安装和配置、优化

    Vim 介绍 Vim 官网:http://www.vim.org/ Vim 安装 CentOS:sudo yum install -y vim Ubuntu:sudo apt-get install ...

  3. NPM install -save 和 -save-dev 区别

    最近在写Node程序的时候,突然对 npm install 的-save和-save-dev 这两个参数的使用比较混乱.其实博主在这之前对这两个参数的理解也是模糊的,各种查资料和实践后对它们之间的异同 ...

  4. 6.【Spring Cloud Alibaba】API网关-SpringCloudGateway

    SpringCloud Gateway是什么?优缺点分析 springCloud Gateway优点 springCloud Gateway缺点 编写SpringCloundGateway pom.x ...

  5. 1.4掌握日志工具的使用——Android第一行代码(第二版)笔记

    Android中的日志工具类是Log(android.util.Log),这个类中提供了如下5个方法来供我们打印日志. Log.v():用于打印那些最为琐碎的.意义最小的日志信息.对应级别verbos ...

  6. 阿里Java架构师分享自己的成长经历,教你如何快速成长为架构师

    架构师是公司的“金领”,很少需要考虑生存的问题,从而有更多的精力思考关键技术,形成“强者愈强”的良性循环.当然,冰冻三尺非一日之寒,成为一名合格的架构师是一个漫长的积累过程.对于大部分的软件开发人员来 ...

  7. 反射机制(reflection)

    一.反射: 1.反射指可以在运行时加载.探知.使用编译期间完全未知的类. 2.程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法: 对于任意一个对 ...

  8. Thingsboard之MQTT设备协议简介

    MQTT基础知识 MQTT是一种轻量级的发布 - 订阅消息传递协议,可能使其最适合各种物联网设备.您可以在此处找到有关MQTT的更多信息.ThingsBoard服务器节点充当MQTT Broker,支 ...

  9. 在vue中继续使用layer.js来做弹出层---切图网

    layer.js是一个方便的弹出层插件,切图网专注于PSD2HTML等前端切图多年,后转向Vue开发.在vue开发过程中引入layer.js的时候遇到了麻烦.原因是layer.js不支持import导 ...

  10. AI Web 2.0

    kali: 192.168.0.103 目标机:192.168.0.105 0X01 扫描端口和目录 a)扫描端口 开启了80和22端口 b)扫描目录 看到两个敏感字样的目录 尝试访问/webadmi ...