题目: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. 微信授权网页登陆,oauth

    1.在微信公众号请求用户网页授权之前.开发人员须要先到公众平台官网中的开发人员中心页配置授权回调域名.请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加http://等协议头. 2.授 ...

  2. Android自己定义View的实现方法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了.回 ...

  3. 爬虫基本操作、requests和BeautifulSoup

    1. 爬虫基本操作 例如舆情系统: 获取汽车之家新闻放到自己数据库里,创建自己的app,发布内容,注明来源,自己创业. URL指定内容获取到 - 发送Http请求:http://www.autohom ...

  4. 点击选中/取消选中flag

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  5. C#动态编译dll或exe

    string strCode = @" using System; using System.Text; using System.Collections.Generic; using Sy ...

  6. Ubuntu16.04上安装mongoDB

    安装MongoDB 现在最新版本是3.4 1: sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F37303 ...

  7. 在fedora25x86下编译opencv的Android版本的过程记录

    准备材料: 1. 32位的Fedora25(不建议使用64位系统----64位系统下也是可以编译的,这里为了简单起见,考虑使用32位操作系统.事实上,本人在64位操作系统下也做了尝试,也完成了编译.) ...

  8. Flatify分页

    Flatify分页:<ul uib-pagination total-items="siteCount" items-per-page="1" max-s ...

  9. 宜信开源|分布式任务调度平台SIA-TASK的架构设计与运行流程

    一.分布式任务调度的背景 无论是互联网应用或者企业级应用,都充斥着大量的批处理任务.我们常常需要一些任务调度系统来帮助解决问题.随着微服务化架构的逐步演进,单体架构逐渐演变为分布式.微服务架构.在此背 ...

  10. python pyinotify模块详解

    转载于http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=23504396&id=2929446 1年多前就看过相关内容了, ...