题目:https://www.luogu.org/problemnew/show/P3646

对于A>1,将答案各位全置1,然后从高位到低位改成0判断是否可行;

用f[i][j]数组代表前i个数分成j组是否可行,转移是枚举最后一段的左端点k,然后看看后面整个一段的和能否满足要求,如果前后都满足就表示i,j状态也可行;

对于A=1,可以贪心地认为分组数量越少越好,所以可行性转化为最优性,省去一维,转移条件同上,取min即可;

先写了个WA一半的版本:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int n,A,B,len;
ll f2[],ans,s[];
bool f[][];//可行性
bool dp1(ll x)
{
memset(f,,sizeof f);
f[][]=;
for(int i=;i<=n;i++)//前i个数分成j段 <- 前k个数分成j-1段
for(int j=;j<=i;j++)
for(int k=;k<i;k++)//
if(((s[i]-s[k])|x)==x)f[i][j]|=f[k][j-];
for(int i=A;i<=B;i++)
if(f[n][i])return ;
return ;
}
bool dp2(ll x)
{
// memset(f2,0x3f,sizeof f2);
f2[]=;
for(int i=;i<=n;i++)
{
ll ad=n+;
for(int j=;j<i;j++)//
if(((s[i]-s[j])|x)==x)ad=min(ad,f2[j]);
f2[i]=ad+;
}
return f2[n]<=B;
}
int main()
{
scanf("%d%d%d",&n,&A,&B);
for(int i=;i<=n;i++)
scanf("%lld",&s[i]);
for(int i=;i<=n;i++)
s[i]+=s[i-];
for(len = ;(1LL << len) <= s[n];len++);len--;//位数
if(A!=)
{
ans=(ll)(<<(len+));ans--;
for(int k=len;k>=;k--)//0!
{
ll tmp=ans-(ll)(<<k);
if(dp1(tmp))ans=tmp;
}
}
else
{
ans=(ll)(<<(len+));ans--;
for(int k=len;k>=;k--)
{
ll tmp=(ll)ans-(<<k);
if(dp2(tmp))ans=tmp;
}
}
printf("%lld",ans);
return ;
}

后来又直接改成别的写法A的,但还是不太明白原来的写法为什么不行,有什么不同。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int n,A,B,len;
ll f2[],ans,s[];
bool f[][];//可行性
ll dp1()
{
ans=;
for(int t=len;t>=;t--)
{
ans+=(1LL<<t)-;
memset(f,,sizeof f);
f[][]=;
for(int i=;i<=n;i++)//前i个数分成j段 <- 前k个数分成j-1段
for(int j=;j<=i;j++)
for(int k=;k<i;k++)//
if(((s[i]-s[k])|ans)==ans)f[i][j]|=f[k][j-];
bool fl=;
for(int i=A;i<=B;i++)fl|=f[n][i];
if(fl)ans-=(1LL<<t)-;
else ans++;
}
return ans;
}
ll dp2()
{
ans=;
for(int t=len;t>=;t--)
{
ans+=(1LL<<t)-;
f2[]=;
for(int i=;i<=n;i++)
{
ll ad=n+;
for(int j=;j<i;j++)//
if(((s[i]-s[j])|ans)==ans)ad=min(ad,f2[j]);
f2[i]=ad+;
}
if(f2[n]<=B)ans-=(1LL<<t)-;
else ans++;
}
return ans;
}
int main()
{
scanf("%d%d%d",&n,&A,&B);
for(int i=;i<=n;i++)
scanf("%lld",&s[i]);
for(int i=;i<=n;i++)
s[i]+=s[i-];
for(len = ;(1LL << len) <= s[n];len++);len--;//位数
if(A==)printf("%lld",dp2());
else printf("%lld",dp1());
return ;
}

APIO2015巴厘岛的雕塑——数位DP的更多相关文章

  1. [APIO2015]巴厘岛的雕塑 贪心+DP+特殊数据优化

    写了好久.... 刚刚调了一个小时各种对拍,,,,最后发现是多写了一个等号,,,,内心拒绝 表示一开始看真的是各种懵逼啊 在偷听到某位大佬说的从高位开始贪心后发现可做 首先考虑小数据(因为可以乱搞) ...

  2. bzoj 4069: [Apio2015]巴厘岛的雕塑【dp】

    居然要对不同的数据写不同的dp= = 首先记得开long long,<<的时候要写成1ll<<bt 根据or的性质,总体思路是从大到小枚举答案的每一位,看是否能为0. 首先对于 ...

  3. 【BZOJ4069】[Apio2015]巴厘岛的雕塑 按位贪心+DP

    [BZOJ4069][Apio2015]巴厘岛的雕塑 Description 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 N 座雕塑,为方便起见,我们把这些雕塑从 ...

  4. bzoj 4069 [Apio2015]巴厘岛的雕塑 dp

    [Apio2015]巴厘岛的雕塑 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 494  Solved: 238[Submit][Status][Dis ...

  5. bzoj千题计划239:bzoj4069: [Apio2015]巴厘岛的雕塑

    http://www.lydsy.com/JudgeOnline/problem.php?id=4069 a!=1: 从高位到低位一位一位的算 记录下哪些位必须为0 dp[i][j] 表示前i个数分为 ...

  6. [APIO2015]巴厘岛的雕塑 --- 贪心 + 枚举

    [APIO2015]巴厘岛的雕塑  题目描述 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有\(N\)座雕塑,为方便起见,我们把这些雕塑从 1 到\(N\)连续地进行 ...

  7. 【BZOJ4069】【APIO2015】巴厘岛的雕塑 [贪心][DP]

    巴厘岛的雕塑 Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description 印尼巴厘岛的公路上有许多的雕塑, ...

  8. [BZOJ4069][Apio2015]巴厘岛的雕塑

    题目大意 分成 \(x\) 堆,是的每堆的和的异或值最小 分析 这是一道非常简单的数位 \(DP\) 题 基于贪心思想,我们要尽量让最高位的 \(1\) 最小, 因此我们考虑从高位向低位进行枚举,看是 ...

  9. 洛谷P3646 [APIO2015]巴厘岛的雕塑(数位dp)

    传送门 话说莫非所有位运算都可以用贪心解决么……太珂怕啦…… 一直把或运算看成异或算我傻逼…… 考虑从高位到低位贪心,如果能使答案第$i$位为0那么肯定比不为$0$更优 然后考虑第$i$位是否能为$0 ...

随机推荐

  1. oracle ORA-06550

    declare  cnt integer; begin     select count(0)     into cnt     from user_all_tables    where table ...

  2. python--函数程序分析

    写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作 import os #加载模块 def xiu(a,b,c): #三个接受值的形参 f = open(a,encod ...

  3. Fedora 25/24/23 nVidia Drivers Install Guide

    https://www.if-not-true-then-false.com/2015/fedora-nvidia-guide/ search Most Popular Featured Linux ...

  4. PHP魔术方法之__call与__callStatic方法

    <?php class human{ private function t(){ } //魔术方法__call /* $method 获得方法名 $arg 获得方法的参数集合 */ public ...

  5. makefile编写---.c .cpp 混合编译makefile 模板

    # c.cpp混合编译的makefile模板 # # BIN = client_system BASE_INSTALL_DIR := /opt/arm-2009q1 BUILD_TOOL_DIR := ...

  6. React Native学习(二)之View

    React Native组件解析(二)之View 0.JSX React的核心机制之一就是虚拟DOM:可以在内存中创建的虚拟DOM元素.React利用虚拟DOM来减少对实际DOM的操作从而提升性能. ...

  7. 2018-11-9-匿名函数&递归函数初识

    1.匿名函数(lambda) 2.递归函数初识

  8. mysql-test-run.pl

    wget https://raw.githubusercontent.com/mysql/mysql-server/5.7/mysql-test/mysql-test-run.pl

  9. 整形范围 运行Java代码的机器

    Java 无关 C C++ 有关  移植  整形溢出

  10. 浏览器访问配置完成的ftp服务器

    在浏览器的地址栏输入: ftp://testuser:testuser@192.168.10.4 testuser 是ftp的用户名和密码: 192.168.10.4 是ftp服务器的IP地址. 亲测 ...