首页 > 其他分享 >dp 练习 2024.3.9

dp 练习 2024.3.9

时间:2024-04-09 16:45:43浏览次数:26  
标签:2024.3 val 钦定 练习 叶子 maxn ll dp define

Luogu8389 [ZJOI2022] 树

考虑容斥,每个点有三个状态:不钦定、钦定都是叶子、钦定都是非叶子。对于每一种钦定状态都计算答案,然后乘上对应容斥系数即可。

叶子的钦定是可做的,考虑非叶子的钦定,我们可以用“容斥套容斥”的思想理解:对于钦定都是非叶子的点 \(i\),考虑用总方案数减去钦定其中之一是叶子的方案数,再加上两者都是叶子的方案数。

把非叶子的钦定放回原容斥里描述:减去总方案数,加上钦定第一棵树中是叶子的方案数、加上钦定第二棵树中是叶子的方案数、减去两棵树中都是叶子的方案数。

和不钦定、钦定叶子的方案加起来,相当于:加上钦定第一棵树中是叶子的方案数、加上钦定第二棵树中是叶子的方案数、减去 \(2\times\) 两棵树中都是叶子的方案数。

设 \(f[i,j,k]\) 表示考虑了前 \(i\) 个点,其中第一棵树中有 \(j\) 个没有被钦定是叶子的点,第二棵树中还剩 \(k\) 个没有被钦定是叶子的点。

转移容易。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn=510, M=1e9;
ll n,mod,f[2][maxn][maxn],ans;
int main(){
	scanf("%lld%lld",&n,&mod);
	for(ll i=1;i<n;i++) f[1][1][i]=i;
	puts("1");
	for(ll i=2;i<n;i++){
		memset(f[i&1],0,sizeof f[i&1]);
		for(ll j=1;j<=n;j++)
			for(ll k=1;k<=n;k++){
				if(!f[i&1^1][j][k]) continue;
				f[i&1][j][k-1]=(f[i&1][j][k-1]+f[i&1^1][j][k]*j*(k-1))%mod;
				f[i&1][j+1][k]=(f[i&1][j+1][k]+f[i&1^1][j][k]*j*k)%mod;
				f[i&1][j][k]=(f[i&1][j][k]-2*f[i&1^1][j][k]*j*k)%mod;
			}
		ans=0;
		for(ll j=1;j<=i;j++)
			ans=(ans+f[i&1][j][1]*j)%mod;
		printf("%lld\n",(ans+mod)%mod);
	}
	return 0;
}

AGC036F Square Constraints

相当于有两个圆,每个位置的取值必须在两个圆中间,求方案数。

本质上还是 \(p_i\in[l_i,r_i]\) 的计数。考虑如果没有下面那个圆怎么做,把 \(r_i\) 从小到大排序,答案就是 \(\prod\limits_i (r_i-i+1)\)。

如果有下面的圆,因为钦定后本质上还是在一段前缀上取值,我们考虑容斥

钦定取值在下面圆内的位置集合 \(S\),不难发现 \(S\in \{0,2,...,n-1\}\),考虑使用 dp 来综合所有的 \(S\)。

但是这样有个问题,我们难以计算方案数。尝试先排序:对于 \(i=n...2n-1\),基准为 \(r_i\);对于 \(i=0...n-1\),基准为 \(l_i-1\)。按基准来排序。

对于未被钦定的位置 \(i\),我们还要知道 \(r_i\) 前面有多少个比他小的数,发现我们只要知道了钦定的位置个数就能算出。因为对于每个钦定的位置 \(i(i<n)\),\(l_i-1\) 总是不大于所有未钦定的位置 \(j(j<n)\) 的 \(r_j\)。

所以我们考虑 dp 开始前先枚举钦定的位置个数,便于计算。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn=510;
ll n,id[maxn],mod,f[maxn][maxn],ans,l[maxn],r[maxn];
bool cmp(ll x,ll y){ ll p=(r[x]<r[y]);
	x=(x<n? l[x]-1:r[x]), y=(y<n? l[y]-1:r[y]);
	return x^y? x<y:p;
}
int main(){
	scanf("%lld%lld",&n,&mod);
	for(ll i=0;i<(n<<1);i++){
		if(i<n) l[i]=ceil(sqrt(n*n-i*i));
		r[i]=sqrt(4*n*n-i*i); id[i+1]=i;
		r[i]=min(r[i],(n<<1)-1);
	} sort(id+1,id+1+(n<<1),cmp);
	for(ll d=0;d<=n;d++){ //printf("d = %lld\n",d);
		memset(f,0,sizeof f);
		f[0][0]=1; ll cnt=0;
		for(ll i=1;i<=(n<<1);i++){
			for(ll j=0;j<=d&&j<=i-1-cnt;j++){
				if(id[i]>=n){
					if(cnt+j<=r[id[i]]) f[i][j]=(f[i][j]+f[i-1][j]*(r[id[i]]+1-cnt-j))%mod;
				}
				else{
					if(n+d+(i-1-cnt-j)<=r[id[i]]) f[i][j]=(f[i][j]+f[i-1][j]*(r[id[i]]+1-n-d-(i-1-cnt-j)))%mod;
					if(j<d&&cnt+j<l[id[i]]) f[i][j+1]=(f[i][j+1]+f[i-1][j]*(l[id[i]]-cnt-j))%mod;
				}
			} cnt+=(id[i]>=n);
		}
		ans=(ans+(d&1? mod-1:1)*f[n<<1][d])%mod;
	} printf("%lld",ans);
	return 0;
}

AGC040E Prefix Suffix Addition

考虑原问题的本质:将 \(x_i\) 分裂为 \(a_i+b_i\),钦定 \(a_0=b_{n+1}=0\),最小化 \(\sum\limits_{i=1}^n[a_{i-1}>a_i]+\sum\limits_{i=1}^n[b_i<b_{i+1}]\)。

挖掘问题的本质很重要,这样能转化模型。

我们暴力,设 \(f[i,j]\) 表示确定了 \(a_{1...i},b_{1...i}\),并且 \(a_i=j\) 的答案。

转移很显然:

\[f[i,j]=\min_{0\le k\le x_{i-1}} \{[k>j]+[x_{i-1}-k<x_i-j]+f[i-1,k]\} \]

  • 一个 trick:注意每次转移最多加 \(2\),并且都是全局贡献,那么 \(f[i,\_]\) 最多 \(3\) 段,直接维护。

设 \(val=\min\limits_{0\le k\le x_{i-1}} f[i-1,k]\),且位置为 \(p\),不难发现 \(f[i,\max(p,x_i-(x_{i-1}-p))...x_i]\) 都会变成 \(val\)。

接着处理 \(val+1\) 的段,是 \([\min(p,x_i-(x_{i-1}-p)),\max(p,x_i-(x_{i-1}-p)))\)。

剩下那段是前缀,等于 \(val+2\)。

顺便可以发现,我们的 \(p\) 是贪心取最小的位置,我们直接维护 \(p_1,p_2,p_3\) 表示三段的起点即可。

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pir pair<ll,ll>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const ll maxn=2e5+10, mod=998244353, iv=mod-mod/2;
ll n,a[maxn],p1,p2,p3,val;
int main(){
	scanf("%lld",&n);
	p1=p2=p3=val=0;
	for(ll i=1;i<=n+1;i++){
		if(i<=n) scanf("%lld",a+i);
		ll q3=min(a[i]+1,max(p3,a[i]-(a[i-1]-p3))),
		q2=max(0ll,min(min(p3,a[i]-(a[i-1]-p3)),max(p2,a[i]-(a[i-1]-p2)))), q1=0, v=val;
		if(q3>a[i]) q3=q2, q2=q1, q1=0, ++v;
		p1=q1, p2=q2, p3=q3, val=v;
	} printf("%lld",val);
	return 0;
}

标签:2024.3,val,钦定,练习,叶子,maxn,ll,dp,define
From: https://www.cnblogs.com/Sktn0089/p/18124294

相关文章

  • ubuntu16.04 wordpress建站教程
    四、wordpress搭建完成本地浏览器输入服务器IP地址,跳转至wordpress安装界面在安装界面中输入数据库密码即可完成安装本地机器输入IP地址/wp-admin进入wordpress后台登录成功......
  • 【C语言】练习:比较十个数的大小
    初始化一个数组,使用for循环输入;把数组中的第一个数字,也就是下标为[0]的数字赋值给一个int类型的变量“max”;使用循环从arr数组中下标为[1]的数字开始对比,如果arr[1]>arr[0],则把arr[1]赋值给max;最后打印出最大数。intmain(){ intarr[10]; for(inti=0;i<10;......
  • 【C语言】练习:分数求和
    计算1/1-1/2+1/3-1/4+1/5……+1/99-1/100的值,打印出结果首先看题,分子不变为1,分母1-100;既然是分数计算,那结果肯定存在小数,所以在开始定义一个double类型的变量“num”;初始化一个int类型的变量“i”,使用for循环产出1-100的值;在for循环里使用if语句来判断分母是偶数......
  • crictl images报错runtime connect using default endpoints: [unix:///var/run/docke
    想试试containerd运行k8s,结果报错还在找dockershim,网上找了解决方法crictl依次查找容器运行时,当查找第一个unix:///var/run/dockershim.sock没有找到,所以报错了,需要你手动指定当前kubernetes的容器运行时,使用什么,例如:kubernetes1.24+之后,dockershim已经变成了cri-docker,所以......
  • 【IP层的校验和与UDP的校验和】+【FPGA实现】
    MAC层的校验是CRC,而IP层也有其校验机制。CRC保证数据包的传输正确; IP头校验和IP头校验和是一种错误检测机制,用于在互联网协议(IP)中保证IP头的数据完整性。当一个IP数据包从源主机发送到目的主机时,它经过许多路由器和交换机,校验和可以帮助这些中间设备检查数据包......
  • rhcsa练习题容易错的地方
    rhcsa练习题容易错的地方yum仓库的配置注意配置yum仓库的时候,baseurl的路径不要写错dnfcleanall&&dnfmakecache//检查错误selinux放行端口的命令修改selinx的文件类型的命令修改了服务配置文件一定要重启服务配置时间同步时间同步的格式修改了配置文件要记......
  • 状压dp——Disease Manangement 疾病管理
    题目描述Alas!AsetofD(1<=D<=15)diseases(numbered1..D)isrunningthroughthefarm.FarmerJohnwouldliketomilkasmanyofhisN(1<=N<=1,000)cowsaspossible.IfthemilkedcowscarrymorethanK(1<=K<=D)differentd......
  • [SDOI2009] Bill的挑战 (状压DP)
    [SDOI2009]Bill的挑战题目描述Sheng_bill不仅有惊人的心算能力,还可以轻松地完成各种统计。在昨天的比赛中,你凭借优秀的程序与他打成了平局,这导致Sheng_bill极度的不满。于是他再次挑战你。这次你可不能输。这次,比赛规则是这样的:给出\(N\)个长度相同的字符串(由小写英文......
  • C语言练习题
    练习一:设某正方形的边长为整数,定义一个sideLen变量存储该边长值(自行设定任意整数边长),并定义一个squareArea变量存储该正方形面积(根据sideLen计算),输出该正方形的边长与面积。#include<stdio.h>intmain(){intsidelen=2,squareArea=sidelen*sidelen;printf(......
  • 题目:宏#define命令练习(3)
    题目:宏#define命令练习(3)Thereisnonutritionintheblogcontent.Afterreadingit,youwillnotonlysufferfrommalnutrition,butalsoimpotence.Theblogcontentisallparallelgoods.Thosewhoareworriedaboutbeingcheatedshouldleavequic......