首页 > 其他分享 >Gym - 101170A[DP+思维]

Gym - 101170A[DP+思维]

时间:2023-05-31 10:06:12浏览次数:61  
标签:suf cnt int Gym mx 最小值 ans 101170A DP


题目链接:https://vjudge.net/problem/Gym-101170A

 

解题思路:

首先要确定的是,改变次数最多不会超过2*n次,因为n最多40,所以我们只要改变每个数的前两个最高位,肯定可以让n个数有序。

然后我们就可以想办法搞个DP[i][j]表示将前i个数变成有序花了j次的最小值。

为什么是最小值呢,维护最小值就是使得高位尽量小,那么就使得后面的数,更有机会直接改变一次高位就可以取得比之前的数大,也就可以保证改变次数越小。

接下来来考虑一下怎么转移,怎么使得花d次变化使得b大于等于a并且尽量靠近a呢?很明显从高位开始看,b[i]要么变为a[i],要么变为a[i]+1,如果变成a[i]+1,也就说明后面怎么变都不能大于a,所以在i位置要变为a[i]+1,这就与a的串i位置后面连续的9的个数和这个连续区间b的9的个数有关。这里就不细说,看代码就知道了,在变为a[i]+1之后,把剩余的d让前d个高位不是0的变为0就可以取得最小值了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mx = 410;
string ans[45][100];
string a,b,c;
int n,m,cmp[mx],up[45][100];
int suf[mx],cnt[mx],vis[mx];
void output(int x,int d)
{
	if(x==1){
		cout << ans[x][d] << endl;
		return ;
	}
	output(x-1,up[x][d]);
	cout << ans[x][d] << endl;
}
bool full(int p,int d){
	for(int i=p;i<m&&d;i++)
	if(a[i]!='0'){
		a[i] = '0';
		d--;
	}
	return !d;
}
bool check(int d){
	for(int i=m-1;i>=0;i--){
		if(a[i]>c[i]) vis[i] = 1;
		else if(a[i]<c[i]) vis[i] = -1;
		else vis[i] = vis[i+1];
	}
	for(int i=0;i<m&&d;i++){
		int pos = i + suf[i+1];
		int w = suf[i+1] - (cnt[i+1]-cnt[pos+1]);
		if(a[i]!=c[i]){
			if(d-1<w||(d-1==w&&vis[pos+1]==-1)){
				if(c[i]=='9') return 0;
				if(a[i]!=c[i]+1) d--;
				a[i] = c[i] + 1;
				return full(i+1,d); 
			}
			a[i] = c[i],d--;
		}else{
			if(d<w||(d==w&&vis[pos+1]==-1)){
				if(c[i]=='9') return 0;
				a[i] = c[i] + 1,d--;
				return full(i+1,d); 
			}	
		}
	}
	return !d && a >= c;
}
int main(){
	ios::sync_with_stdio(false);
	cin >> n >> m;
	ans[0][0] = string(m,'0');
	for(int i=1;i<=n;i++){
		cin >> b;
		for(int j=m-1;j>=0;j--){
			cnt[j] = cnt[j+1];
			if(b[j]=='9') cnt[j]++;
		}
		for(int k=0;k<=2*n;k++){
			ans[i][k] = string(m+1,'9');
			for(int j=0;j<=k;j++){
				c = ans[i-1][k-j];
				if(c.length()!=m) continue;
				for(int w=m-1;w>=0;w--){
					suf[w] = 0;
					if(c[w]=='9') suf[w] = suf[w+1] + 1;
				}
				a = b;
				bool ok = check(j);
				if(ok&&ans[i][k]>a){
					ans[i][k] = a;
					up[i][k] = k-j;
				}
			}
		}
	}
	for(int i=0;i<=2*n;i++)
	if(ans[n][i].length()==m){
		output(n,i);
		break;
	}
    return 0;
}

 

标签:suf,cnt,int,Gym,mx,最小值,ans,101170A,DP
From: https://blog.51cto.com/u_12468613/6384503

相关文章

  • Gym - 101480J[判环+Hash]
    题目链接:https://vjudge.net/problem/Gym-101480J 解题思路:因为度最多为3所以流量最多不超过3对于在同一个连通块上:flow==1对于在同一个环上(可以看做有向图强连通):flow==2对于某一个点对,删除任意一条边他们还是在同一个环上,说明去掉一个流量他们的流量还是2,所以这种情况:f......
  • Gym - 100851J [随机+01集合]
    题目链接:https://vjudge.net/problem/Gym-100851J 解题思路:出题故意不给501次,就是要让我们去随机找出值为n/2的串,每次最坏的情况随机一个串值是n/2的概率是:约等于0.022。那我们随机400不中的概率是 = 0.000309336,概率非常低,所以几乎是可以找到的。找到之后s串后,同时改变0和i......
  • Gym - 100851L [二分+线性推导]
    题目链接:https://vjudge.net/problem/Gym-100851L 解题思路:根据题目知道,墙的两边是不能放石头的,所以最终的结果肯定会收到两边墙的限制,从而使得答案不会超过1e9+1e5。此外我们再去二分最大高度,一个明显的结论就是以i为最高点建墙的话最少花费肯定是建一个金字塔形的墙面。但由于......
  • Gym - 100519I [NONE]
    题目链接:https://vjudge.net/problem/Gym-100519I 解题思路:先挂在这里#include<bits/stdc++.h>#defineinf0x3f3f3f3fusingnamespacestd;typedeflonglongll;constintmx=3e5+10;boolvis[mx];inttop,pri[mx];voidinit(){ for(inti=2;i<mx;i++){ if(!vis[i......
  • Codeforces #564 (Div. 2) D. Nauuo and Circle[树形DP]
    题目链接:http://codeforces.com/contest/1173/problem/D 解题思路:首先得知道按照圆周顺序的话,那么一颗子树必须存放在连续的一段区间里面,现在我们假设根节点是1,那么一颗为u做根节点的子树他的方案数就是各个儿子的方案数的乘积最后再乘以儿子个数+1(u节点本身)的排列方案数。所......
  • 4543: [POI2014]Hotel加强版[树形DP+长链剖分]
    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4543 解题思路:长链剖分定义:f[i][j]表示以i为根节点的子树,有多少个节点和i的距离是j的.g[i][j]表示以i为根节点的子树,在子树外一个距离i为j的点可以跟i子树内的两个点组成两两相等的方案数.那么就有:f[u][j+1]+=f[v......
  • 插头DP 备忘
    插头DP备忘以前一直觉得没必要学,就是普通的状压,发现不学一下写起来有点难受的。最好的学习资料大概就是cdq的论文了。原文叫基于连通性状态压缩的动态规划问题。最常见的问题形式就是给个网格图,求某种回路或者类似的图形最优化或者计数。核心思想是把他转化为\(dp\),需要......
  • dp-runtime去Kafka依赖方案
    背景现有原生kafkaconnectruntime,在客户环境运行遇到诸多问题,问题列表如下:强依赖Kafka集群做任务分配、connector配置信息、connector状态管理、source进度维护等等当遇到数据量大、并行数多,topic数量较多时,可能引发kakfa集群的不稳定包括(节点宕机,controller切换等)从而引......
  • DPU54可替代AU9254串口USB1.1 hub芯片
    产品概述DPU54是一款高性能、低功耗4口全速USB1.1HUB控制器,上行端口兼容全速12MHz模式,4个下行端口兼容全速12MHz、低速1.5MHz两种模式。DPU54采用状态机单事务处理架构,而非单片机架构,多个事务缓冲区,这样减小了芯片的系统响应时间,用最少的硬件资源实现了USB1.1全速传......
  • UDP协议
    UDP协议1.UDP协议的特点无连接性:UDP是无连接的,发送端发送数据时不需要与接收端建立连接,也不会维护连接状态。不可靠性:UDP不提供可靠的数据传输。发送端将数据打包成数据报(Datagram),直接发送给接收端,不保证数据的完整性、顺序和是否到达。高效性:由于没有连接建立和维护的......