JZOJ5935. 【NOIP2018模拟10.29】小凯学数学

本文介绍了一种使用区间动态规划解决特定01序列问题的方法。通过枚举答案并设置状态f[i][j][k]来表示区间i-j是否能得到答案k,实现了O(n^3)的算法。文章提供了完整的C++代码实现,并讨论了数据范围和转移方程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

preface

  考试还是第一次这么顺畅的dp,几分钟就切了。。

分析

  数据范围明示O(n3)算法,而且并不需要什么(a+b)>>1的规律。

  考虑区间dp。因为a[i]很小所以可以直接枚举答案,设f[i][j][k]表示区间i-j是否能得到答案k,转移就很明显了,f[i][j][((a&b)+(a|b))>>1]=f[i][k][a]|f[k+1][j][b]。最后直接输出就行了,注意a[i]范围是0到7,因为没算0爆炸的兄弟走好。

code 

#include<bits/stdc++.h>
#define maxn 200
#define ll long long
#define reg register
using namespace std;
int n,a[maxn];
bool f[maxn][maxn][10];
int main()
{
    scanf("%d",&n);
    for(reg int i=1;i<=n;i++) 
    {
        scanf("%d",&a[i]);        
        f[i][i][a[i]]=true;
    }
    for(reg int l=2;l<=n;l++)
    {
        for(reg int i=1;i<=n && i+l-1<=n;i++)
        {
            reg int j=i+l-1;
            for(reg int k=i;k<=j;k++)
                for(reg int a=0;a<=7;a++) if(f[i][k][a])
                    for(reg int b=0;b<=7;b++) if(f[k+1][j][b])
                    {
                        int tmp=((a&b)+(a|b))>>1;
                        f[i][j][tmp]=1;
                    }
        }
    }
    for(reg int i=0;i<=7;i++) if(f[1][n][i]) printf("%d ",i);
    return 0;
}

 

转载于:https://www.cnblogs.com/wCTSd/p/9883417.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值