构造一个01矩阵,其中格子$(i,j)$​​​​​对应于第$ik+j$​​个​​​的位置(其中$0\le i<\lceil\frac{n}{k}\rceil,0\le j<k$​​​,位置从0开始编号)​​,那么问题即有以下限制:

1.$(\lceil\frac{n}{k}\rceil-1,j)$(其中$n-(\lceil\frac{n}{k}\rceil-1)k\le j<k$​不能被选择(强制为0)

2.$\forall 1\le i<\lceil\frac{n}{k}\rceil$和$0\le j<k$,$(i-1,j)$和$(i,j)$不同时为0

3.$\forall 0\le i<\lceil\frac{n}{k}\rceil$和$0\le j<k$,$(i,j)$和$(i,(j+1)mod\ k)$不同时为0

关于这个问题,考虑状压dp,有两种dp方式:

1.从上到下、从左到右dp,dp到$(i,j)$​时记录$(i,[0,j])$​和$(i-1,(j,k))$​的01状态即可,复杂度为$o(n2^{k})$

2.从左到右、从上到下dp,dp到$(i,j)$​时记录$([0,\lceil\frac{n}{k}\rceil),0),([0,i],j)$​和$((i,\lceil\frac{n}{k}\rceil),j-1)$​的01状态即可,复杂度为$o(n2^{\frac{2n}{k}})$(前者可以初始枚举来方便实现)

将两者合并,即对$k^{2}\le 2n$​​和$k^{2}>\sqrt{2n}$​​分别使用第1种和第2种方式dp

同时,注意到状态序列中不能存在相邻的1,因此$2^{n}$对应的合法状态数仅为$F_{n+2}$(其中$F$为斐波那契数列),根据通项公式约为$1.618^{n}$​

最终,总复杂度为$o(n\cdot 1.618^{\sqrt{2n}})$​,可以通过

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 305
4 #define M 200005
5 #define L (1<<24)
6 #define mod 1000000007
7 #define ll long long
8 #define Add(x,y) x=(x+y)%mod
9 vector<int>v;
10 int t,n,k,ans,w[N],vis[L],id[L],f[N<<1][M];
11 int main(){
12 scanf("%d",&t);
13 while (t--){
14 scanf("%d%d",&n,&k);
15 for(int i=0;i<n;i++)scanf("%d",&w[i]);
16 int r=(n+k-1)/k,c=k;
17 ans=mod-1;
18 if (k*k<=2*n){
19 v.clear();
20 for(int i=0;i<(1<<c);i++){
21 vis[i]=((vis[i>>1])|((i&3)==3));
22 if (!vis[i]){
23 id[i]=v.size();
24 v.push_back(i);
25 }
26 }
27 for(int i=0;i<=n;i++)
28 for(int S=0;S<v.size();S++)f[i][S]=0;
29 f[0][0]=1;
30 for(int i=0;i<n;i++)
31 for(int S=0;S<v.size();S++){
32 Add(f[i+1][id[v[S]>>1]],f[i][S]);
33 if ((v[S]&((1<<c-1)|1))==0)Add(f[i+1][id[(v[S]>>1)|(1<<c-1)]],(ll)w[i]*f[i][S]);
34 }
35 for(int S=0;S<v.size();S++)Add(ans,f[n][S]);
36 }
37 else{
38 v.clear();
39 for(int i=0;i<(1<<r);i++){
40 vis[i]=(vis[i>>1])+((i&3)==3);
41 if (vis[i]<=1){
42 id[i]=v.size();
43 v.push_back(i);
44 }
45 }
46 for(int SS=0;SS<v.size();SS++){
47 if (vis[v[SS]])continue;
48 for(int i=0;i<=r*(c-1);i++)
49 for(int S=0;S<v.size();S++)f[i][S]=0;
50 f[0][SS]=1;
51 for(int i=0;i<r;i++)
52 if (v[SS]&(1<<i))f[0][SS]=(ll)w[i*c]*f[0][SS]%mod;
53 for(int j=1;j<c;j++)
54 for(int i=0;i<r;i++){
55 int k=(j-1)*r+i,pos=i*c+j;
56 for(int S=0;S<v.size();S++){
57 Add(f[k+1][id[v[S]>>1]],f[k][S]);
58 if ((pos<n)&&((v[S]&1)==0)&&((!i)||((v[S]&(1<<r-1))==0)))Add(f[k+1][id[(v[S]>>1)|(1<<r-1)]],(ll)w[pos]*f[k][S]);
59 }
60 }
61 for(int S=0;S<v.size();S++)
62 if ((v[S]&(v[SS]>>1))==0)Add(ans,f[r*(c-1)][S]);
63 }
64 }
65 printf("%d\n",ans);
66 }
67 return 0;
68 }

[hdu6984]Tree Planting的更多相关文章

  1. HDU 6984 - Tree Planting(数据分治+状压 dp)

    题面传送门 傻逼卡常屑题/bs/bs,大概现场过得人比较少的原因就是它比较卡常罢(Fog 首先对于这样的题我们很难直接维护,不过注意到这个 \(n=300\) 给得很灵性,\(k\) 比较小和 \(k ...

  2. 洛谷P3038 [USACO11DEC]牧草种植Grass Planting

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  3. AC日记——[USACO11DEC]牧草种植Grass Planting 洛谷 P3038

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  4. 洛谷 P3038 [USACO11DEC]牧草种植Grass Planting

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  5. USACO Grass Planting

    洛谷 P3038 [USACO11DEC]牧草种植Grass Planting 洛谷传送门 JDOJ 2282: USACO 2011 Dec Gold 3.Grass Planting JDOJ传送 ...

  6. P3038 [USACO11DEC]牧草种植Grass Planting

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  7. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  8. SAP CRM 树视图(TREE VIEW)

    树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...

  9. 无限分级和tree结构数据增删改【提供Demo下载】

    无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...

随机推荐

  1. js 手动实现 promise.all的功能

    在中高级面试中,实现一个promise.all是一个频率较高的面试题 首先分析下 promise.all(),(参考MDN) 接收一个promise的iterable类型(注:Array,Map,Se ...

  2. Django对表单进行增删改查

    查 首先在url中写好路径 其次在后面参数的views里写函数类xxxxxxx的基本逻辑 定义一个函数xxxxxxx,继承request,注意这个request对数据库操作结果都会存放在request ...

  3. 题解 [PA2019]Trzy kule

    link Description 对于两个长度为 \(n\) 的 \(01\) 串 \(a_1,a_2,\dots,a_n\) 和 \(b_1,b_2,\dots,b_n\),定义它们的距离 \(d( ...

  4. Mybatis 二级缓存应用 (21)

    [MyBatis 二级缓存] 概述:一级缓存作用域为同一个SqlSession对象,而二级缓存用来解决一级缓存不能夸会话共享,作用范围是namespace级,可以被多个SqlSession共享(只要是 ...

  5. Beta-技术规格说明书

    项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-计划-功能规格说明书 一.架构与技术栈 1.整体架构 本项目的整体架构如上图所示.下面我们将对涉及 ...

  6. Seata的一些概念

    Seata的一些概念 一.什么是seata 二.AT模式的介绍 1.前提条件 2.整体机制 3.读写隔离的实现 1.写隔离 2.读隔离 三.事务分组 1.事务分组是什么? 2.通过事务分组如何找到后端 ...

  7. virtual box搭建虚拟机nat和host only网络配置实用

    virtual box搭建虚拟机nat和host only网络配置实用 一.背景 二.需求 二.设置虚拟机的网络 1.创建一个全局的nat网络 2.添加主机网络管理器 3.设置虚拟机网络 1.网卡1设 ...

  8. webpack基础以及webpack中babel的配置

    webpack 安装 npm 初始化,控制台输入 npm init -y webpack 安装 npm i webpack webpack-cli -D 新建 webpack.config.js co ...

  9. FastAPI 学习之路(三十三)操作数据库

    通过创建pydantic模型进行验证提交数据 from pydantic import BaseModel class UserBase(BaseModel): email: str class Us ...

  10. linux下的IO模型---学习笔记

    1.linux文件系统和缓存 文件系统接口 文件系统-一种把数据组织成文件和目录的存储方式,提供了基于文件的存取接口,并通过文件权限控制访问. 存储层次 文件系统缓存 主存(通常时DRAM)的一块区域 ...