首页 > 其他分享 >J. Abstract Painting (2020 CCPC 长春)

J. Abstract Painting (2020 CCPC 长春)

时间:2023-02-16 11:14:00浏览次数:46  
标签:1050 std int Abstract 2020 区间 Painting fix dp

J. Abstract Painting

tag:dp

题目链接

题意:

有个很抽象的人要画一幅抽象画,这个抽象画只需要画圆圈就完事了(我上我也行)
需要满足以下条件

  • 圆心都必须在x轴上的[1,n]上,且必须都是整数点。(2≤n≤10^3)
  • 圆的半径为整数,只能取{1,2,3,4,5}。
  • 圆和圆之间最多一个交点,即要么相切要么不相交。
    此外原本x轴上就有一些圆
    我们需要求可行的绘画方案数(ps: 一个圆都不画也算一种方案)

做法:

这道题的做法主要有区间dp和状压dp两种,我认为区间dp好写很多,下面我们只讲区间dp的做法
首先我们可以将圆抽象为区间,圆心x,半径r,我们可以表示为[x-r,x+r]
如果两个区间交叉着了,那么显然不合法
在进行区间dp之前我们需要两个数组来辅助,fix[l][r]标记原本就有的圆,ban[l][r]标记不合法的圆
我们设 dp[l][r][0/1] 表示区间l,r之内的方案数,0、1表示这些方案中存不存在圆[l,r]
首先我们可以想到一个很简单的转移,如果我们可以画出一个[l,r]的圆,那么显然 dp[l][r][1] = dp[l][r][0]
剩下的转移方法就比较细节,请配合代码注释食用

代码:

#define fst std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout << std::fixed << std::setprecision(20)
#define le "\n"
#define ll long long 
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+50;
const int mod=1e9+7;
bool fix[1050][1050],ban[1050][1050];//标记原本就有的圆,
ll dp[1050][1050][2];

int main(){
    int n,k,x,r;
    cin>>n>>k;
    for(int i=1;i<=k;i++){
        cin>>x>>r;
        fix[x-r][x+r]=true;

        for(int i=0;i<x-r;i++){
            for(int j=x-r+1;j<x+r;j++){
                ban[i][j]=true;
            }    
        }

        for(int i=x-r+1;i<x+r;i++){
            for(int j=x+r+1;j<=n;j++){
                ban[i][j]=true;
            }
        }
    }
    
    for(int i=0;i<n;i++) dp[i][i+1][0]=1;//最小的圆是[i,i+2]
    
    for(int len=2;len<=n;len++){
        for(int l=0,r=len;r<=n;l++,r++){
            if(ban[l][r]) continue;

            dp[l][r][0]=(dp[l+1][r][0]+dp[l+1][r][1])%mod; 
            //首先继承一下 [l+1,r] 的方案数,现在左边多了一个点l,我们固定左端点l,枚举右端点来更新状态
            for(int m=l+2;m<=min(l+10,r);m+=2){
                dp[l][r][0]=(dp[l][r][0]+dp[l][m][1]*(dp[m][r][0]+dp[m][r][1]))%mod;
            }
            
            if((r-l)%2==0&&r-l<=10) dp[l][r][1]=dp[l][r][0]; 
            //能画个左右端点为l,r的圆,那就直接套上去,此时画或者不画方案数一致

            if(fix[l][r]) dp[l][r][0]=0;
            //原本就有画在l,r的园,不可能不画
        }
    }
    
    cout<<(dp[0][n][0]+dp[0][n][1])%mod<<le;
    
    return 0;
} 

标签:1050,std,int,Abstract,2020,区间,Painting,fix,dp
From: https://www.cnblogs.com/touchfishman/p/17125974.html

相关文章

  • Java开发工具IntelliJ IDEA 2020.2完整授权流程
    最近几年,Java的技术栈发展的非常快,Java作为一门十分流行的面向对象编程语言,其开发工具也是非常多的,当然因为接触时间长短以及个人喜好,每个人都有自己的选择。对此,我对目前......
  • [Typescript] Creating Chainable Method Abstractions with Generics and the Builde
    import{expect,it}from"vitest";import{fetchUser}from"fake-external-lib";typeMiddleware<TInput,TOutput>=(input:TInput)=>TOutput;classDyna......
  • 2020-11-10
    ​CSS中的BFC详解​一、何为BFC     BFC(BlockFormattingContext)格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器......
  • 2020-11-10
    Vuex从使用到原理解析一、Vuex是什么  Vuex是专门为Vuejs应用程序设计的状态管理工具。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的......
  • 「CSP-J2020」 直播获奖 —— 桶排序例题
    (oh!多么美好的一天)看题!原题链接(洛谷)[CSP-J2020]直播获奖题目描述NOI2130即将举行。为了增加观赏性,CCF决定逐一评出每个选手的成绩,并直播即时的获奖分数线。本次竞......
  • Dumb feature Gym - 102020D 【 字典树 】
    D-Dumbfeature Gym-102020D  &:字典树的模板题,根据来的串建树,再查询。不过当时没弄出来,要映射一下子,把字母映射成键盘上的数字。ps:这题的数据应该是有问题,只......
  • Marvelous Necklace Gym - 102020M
    M-MarvelousNecklace Gym-102020M &:前缀和。#include<cstdio>#include<algorithm>#include<bits/stdc++.h>usingnamespacestd;typedeflonglongl......
  • abstract 抽象类
     约束~抽象方法,只有方法名字,没有方法的实现不能new这个抽象类,只能靠子类去实现它;约束!抽象类中可以写普通方法~抽象方法必须在抽象类中~......
  • abstract 抽象
    abstract抽象类:不能具体实例化的类,不能创建对象。1.不能new这个抽象类。只能靠子类去实现它:约束!---所以我们不能用final修饰我们所谓的new是指:抽象类类名抽象类对象......
  • 2019-2020 ICPC, Asia Jakarta L - Road Construction 网络流
    直接用城市建点的话不好表达连边的关系考虑把每条边看作左部点右部点的话朴素想法是工人,但是也不好表达工人和材料的关系发现工人的信息可以整合成一共有多少种材料,每种......