首页 > 其他分享 >CF803E Roma and Poker 差分约束

CF803E Roma and Poker 差分约束

时间:2024-11-09 16:08:36浏览次数:1  
标签:Poker le end int add Roma CF803E cases dis

CF803E Roma and Poker

W 为 \(1\),L 为 \(-1\),D 为 \(0\),前 \(i\) 个字符的和为 \(dis_i\)。

则有:

  • 当第 \(i\) 位为 W 时:

    \[dis_i-dis_{i-1}=1 \]

    可以推出:

    \[\begin{cases} dis_i-dis_{i-1}\le 1\\ dis_i-dis_{i-1}\ge 1\\ \end{cases} \]

    转为差分约束形式:

    \[\begin{cases} dis_i-dis_{i-1}\le 1\\ dis_{i-1}-dis_i\le -1\\ \end{cases} \]

    建边操作:

    add(i-1,i,1);
    add(i,i-1,-1);
    
  • 当第 \(i\) 位为 L 时:

    \[\begin{cases} dis_i-dis_{i-1}\le -1\\ dis_{i-1}-dis_i\le 1\\ \end{cases} \]

    建边操作:

    add(i-1,i,-1);
    add(i,i-1,1);
    
  • 当第 \(i\) 位为 D 时:

    \[\begin{cases} dis_i-dis_{i-1}\le 0\\ dis_{i-1}-dis_i\le 0\\ \end{cases} \]

    建边操作:

    add(i-1,i,0);
    add(i,i-1,0);
    
  • 当第 \(i\) 位为 ? 时:

    \[\begin{cases} dis_i-dis_{i-1}\le 1\\ dis_{i-1}-dis_i\le 1\\ \end{cases} \]

    建边操作:

    add(i-1,i,1);
    add(i,i-1,1);
    
  • 绝对值等于 \(k\):

    有两种情况:

    \[\begin{cases} dis_n-dis_0\le k\\ dis_n-dis_0\ge k\\ \end{cases} \begin{cases} dis_n-dis_0\le -k\\ dis_n-dis_0\ge -k\\ \end{cases} \]

    改写:

    \[\begin{cases} dis_n-dis_0\le k\\ dis_0-dis_n\le -k\\ \end{cases} \begin{cases} dis_n-dis_0\le -k\\ dis_0-dis_n\le k\\ \end{cases} \]

    建边:

    add(n,0,-k);
    add(0,n,k);
    
    add(0,n,-k);
    add(n,0,k);
    
  • 前缀的绝对值小于 \(k\):

    \[\begin{cases} dis_i-dis_0\le k-1\\ dis_i-dis_0\ge -k+1\\ \end{cases} \]

    改写:

    \[\begin{cases} dis_i-dis_0\le k-1\\ dis_0-dis_i\le k-1\\ \end{cases} \]

    建边:

    add(0,i,k-1);
    add(i,0,k-1);
    

将以上条件全部建边,跑 SPFA 即可。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,k;
char s[1010];
int dis[1010],cnt[1010];
bool vis[1010];
int tag1,tag2;
queue<int>q;
struct edge{
	int v,w,nxt;
}e[100010];
int head[1010],tot;
void add(int u,int v,int w){
	e[tot]={v,w,head[u]};
	head[u]=tot++;
}
bool spfa(int s){
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(cnt,0,sizeof(cnt));
	q.push(s);
	vis[s]=1,dis[s]=0;
	while(!q.empty()){
		int u=q.front();q.pop();
		vis[u]=0;
		for(int i=head[u];i!=-1;i=e[i].nxt){
			if(i==tag1||i==tag2)continue;
			int v=e[i].v,w=e[i].w;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				cnt[v]=cnt[u]+1;
				if(cnt[v]>n)return 0;
				if(!vis[v])q.push(v),vis[v]=1;
			}
		}
	}
	return 1;
}
int main(){
	memset(head,-1,sizeof(head));
	cin>>n>>k;
	scanf("%s",s+1);
	for(int i=1;i<=n;i++){
		if(s[i]=='W')add(i-1,i,1),add(i,i-1,-1);
		if(s[i]=='L')add(i-1,i,-1),add(i,i-1,1);
		if(s[i]=='D')add(i-1,i,0),add(i,i-1,0);
		if(s[i]=='?')add(i-1,i,1),add(i,i-1,1);
		if(i!=n)add(0,i,k-1),add(i,0,k-1);
	}
	add(n,0,-k),add(0,n,k);
	tag1=tag2=-1;
	if(spfa(0)){
		for(int i=1;i<=n;i++){
			switch(dis[i]-dis[i-1]){
				case 1:cout<<'W';break;
				case 0:cout<<'D';break;
				case -1:cout<<'L';break;
			}
		}
		return 0;
	}
	tag1=tot-1,tag2=tot-2;
	add(0,n,-k),add(n,0,k);
	if(spfa(0)){
		for(int i=1;i<=n;i++){
			switch(dis[i]-dis[i-1]){
				case 1:cout<<'W';break;
				case 0:cout<<'D';break;
				case -1:cout<<'L';break;
			}
		}
		return 0;
	}
	cout<<"NO";
	return 0;
}

标签:Poker,le,end,int,add,Roma,CF803E,cases,dis
From: https://www.cnblogs.com/UserJCY/p/18536908

相关文章

  • 从模糊搜索到语义搜索的进化之路——探索 Chroma 在大模型中的应用价值
    目录从模糊搜索到语义搜索的进化之路——探索Chroma在大模型中的应用价值一、引言二、实现语义搜索的数据库Chroma1、语义搜索是什么2、Chroma语义搜索的原理三、如何在项目中应用Chroma1、Chroma的实际应用场景2、安装Chroma(python环境) 3、创建嵌入索引4、查......
  • Educational Codeforces Round 20 E. Roma and Poker
    差分约束我们记W表示\(1\),L表示\(-1\),D表示\(0\),然后记前\(i\)位的前缀和是\(dis[i]\)。则我们可以根据题面得到如下约束。当前位是W,则有\[\left\{\begin{matrix}dis[i]-dis[i-1]\le1\\dis[i-1]-dis[i]\le-1\end{matrix}\right.\]当前位是L,则有\[\left\{\begin{m......
  • CSP-J2024 T1(poker/扑克)题解
    洛谷CSP-J2024自测指路前情提要:虽然洛谷讨论区里大多数都是倾向用哈希解决该题,但实际上可以用一些邪门小技巧来A这道题awa先来读题。题目中说小P想知道他至少得向小S借多少张牌,才能让从小S和小Q借来的牌中,可以选出52张牌构成一副完整的扑克牌。题目说了是求至少要......
  • Ubuntu系统中,使用matplotlib画图调用times new romain字体报错 findfont: Font family
    画图时报错,缺少字体findfont:Fontfamily['TimesNewRoman']notfound.FallingbacktoDejaVuSans.有两种解决方式:方式一:在线安装msttcorefonts包#安装msttcorefonts包这种方式需要ubuntu能连外网,否则因为访问source-forge失败而告终sudoaptupdatesudoapti......
  • 手把手教你用linux安装Gromacs(2024 GPU-CUDA)
    文章目录1.Gromacs介绍2.Gromacs安装一、基础软件1.gcc下载安装2.g++下载安装3.python4.Cmake二、显卡驱动和CUDA安装1.显卡驱动2.CUDA安装3.Gromacs-2024GPU-CUDA安装可能遇到的问题1.错误一原因:解决方法:2.错误二原因:解决方法:3.错误三4.错误四结束语1.G......
  • 磁场发生装置-电磁铁系列 Electromagnet
    功能简介上海天端实业有限公司电磁铁系列产品,可提供可调均匀强磁场,稳定性高,可控性强。适用于科研单位,高等院校及工厂做物质磁性实验,具有多种用途可配用于磁性材料测量装置、振动样品磁强计、霍尔效应研究、磁光效应研究、磁电阻效应研究、磁致伸缩研究、转矩磁强计、力法磁强......
  • GROMACS 初学者入门理解-讲故事
    想要了解GROMACS的可以看过来,自己摸索了一个月才搞明白一点点,网上很多信息根本看不下去,都是专有名词,直接劝退,老是讲不到重点,看完下面这个故事你应该能听懂了,具体gromacs怎么用还是要学,这里能让你快速认识gromacsGROMACS运行起来需要那些文件:体系结构文件gro(),top文件,itp文件,mdp......
  • 使用RAG-Chroma和LangChain构建强大的问答系统
    标题:使用RAG-Chroma和LangChain构建强大的问答系统内容:使用RAG-Chroma和LangChain构建强大的问答系统引言在人工智能和自然语言处理领域,检索增强生成(Retrieval-AugmentedGeneration,RAG)技术正在迅速崛起。本文将介绍如何使用RAG-Chroma模板和LangChain框架构建......
  • easy-es:java: 程序包org.dromara.easyes.core.core不存在
    问题描述:运行easy-es官网的springboot集成demo时报错:java:程序包org.dromara.easyes.core.core不存在问题分析:Ctrl+鼠标左键进入org.dromara.easyes.core下,查找发现BaseEsMapper在org.dromara.easyes.core.kernel目录下,而非org.dromara.easyes.core.core下解决方法......
  • VannaAI(带有 Ollama 和 ChromaDB)示例程序在训练模型步骤失败
    我开始测试VannaAI,并且我正在运行一个基于使用Ollama、ChromaDB为Postgres生成SQL的示例程序:fromvanna.ollamaimportOllamafromvanna.chromadbimportChromaDB_VectorStoreclassMyVanna(ChromaDB_VectorStore,Ollama):def__init__(self,confi......