牛客 7.13 月赛(留 C逆元 Ddp)

B-最少剩几个?_牛客小白月赛98 (nowcoder.com)

思路

奇数+偶数 = 奇数;奇数*偶数 = 奇数

所以在既有奇数又有偶数时,两者结合可以同时删除

先分别统计奇数,偶数个数

若偶个数大于奇个数,答案是偶个数-奇个数

若奇个数大于偶个数,奇数个数减去偶个数再对2取模

ac代码
复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

int main()
{
    IOS;
    int n,ans;
		int ji=0,ou=0;
		cin>>n;
		vector<ll>a(n);
		for(int i=0;i<n;i++) 
		{
			cin>>a[i];
			if(a[i] & 1) ji++;
			else ou++; 
		}
		if(ou>ji)  ans=ou-ji;
		else{
			if((ji-ou)%2) ans=1;
			else ans=0;
		}

		cout<<ans<<endl;   
		return 0;
}

C-两个函数_牛客小白月赛98 (nowcoder.com)

(超时问题如何解决)

初始代码(超时)
复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

int main()
{
    IOS;
    ll q,a,x;
		cin>>q;
		for(int i=0;i<q;i++)
		{
			ll ans=0;
			cin>>a>>x;
			if(x==1) ans=(a*x)%998244353;
			else{
				for(int i=1;i<x;i++)
					{
						ans+=(a*(a%998244353*i)%998244353)%998244353;
						ans%=998244353;					
					}
			}
			ans%=998244353;
			cout<<ans<<endl;
		}
		return 0;
}
解决思路
  1. 快速幂

时间复杂度是 O(log n),相比于直接进行指数运算,大大提高了计算效率

快速幂代码

复制代码
int FastPow(int a,int x,int mod)
{
	int ans = 1;
	a%=mod;
	while(x)
	{
		if(x&1) ans=(ans*a)%mod;
		a= (a*a)%mod;
		x>>=1;
	}
	return ans;
}
  1. 递推式

因为是求和过程,可以用递推式

ac代码
复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
ll mod=998244353;

int main()
{
    IOS;
    ll q,a,x;
		cin>>q;
		for(int i=0;i<q;i++)
		{
			ll ans=0;
			cin>>a>>x;
			if(x==1) ans=a%mod;
            else 
            {
                a = a*a %mod;
                ans=(x-1)*x/2 %mod *a %mod;
            }
			cout<<ans<<endl;
		}
		return 0;
}

D-切割 01 串 2.0_牛客小白月赛98 (nowcoder.com)

思路:
  1. 前缀和

记录在索引的每一个位置处之前,0或1的个数

2.dp

dp[i][j] 表示考虑前 i 个字符时,最多可以进行多少次切割;对于每个长度 len,遍历所有可能的切割起点 l,使得 l + len - 1 不超过序列的长度;对于每个起点 l,计算可能的切割终点 r;

对于每个起点 l 和终点 r,遍历所有可能的切割分割点 k,使得 klr 之间;

动态规划过程的关键在于,通过递归地考虑所有可能的切割方式,并使用前缀和数组来快速计算分割点 k 两侧的子串中0和1的累计数量。通过这种方式,算法能够高效地找到满足条件的切割次数的最大值

代码
复制代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

using namespace std;

/*
算法:区间DP + 前缀和 O(N*N*N)
数据结构:s0,s1前缀和数组 + 二维dp[l][r]
*/

const int N = 510;

int s0[N], s1[N];
int dp[N][N];

void solve() {
    int n, L, R;
    string s;
    cin >> n >> L >> R >> s;
    
    s = " " + s;
    for (int i = 1; i <= n; i ++ )
        s0[i] = s0[i - 1] + (s[i] == '0'),
        s1[i] = s1[i - 1] + (s[i] == '1');
    
    for (int len = 1; len <= n; len ++ )
        for (int l = 1; l <= n; l ++ )
        {
            int r = l + len - 1;
            if (r > n) break;
            for (int k = l; k < r; k ++ )
            {
                int c0 = s0[k] - s0[l - 1];
                int c1 = s1[r] - s1[k];
                if (L <= abs(c0 - c1) && abs(c0 - c1) <= R) 
                    dp[l][r] = max(dp[l][r], 1 + dp[l][k] + dp[k + 1][r]);
            }
        }
    
    cout << dp[1][n] << '\n';
}

signed main() {
    IOS;
    int t = 1;
//    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}
相关推荐
蒸蒸yyyyzwd1 小时前
从面经中学到的三件事
c++·笔记
时时三省1 小时前
【时时三省】计算机c语言二级考试选择题重点
c++
罗西的思考1 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 --- (2)--- 训练
人工智能·算法·机器学习
深圳市方中禾科技2 小时前
FZH1625 LCD 驱动芯片深度评测与实战指南
算法·led
我不会起名字3223 小时前
一天一道算法题(34):回溯法的经典例题(子集)
java·数据结构·python·算法·golang·深度优先·力扣
ThornArmor4 小时前
重铸1996|肉体渲染:关节的裂缝:分段模型积木拼装与未成熟的 RSP 矩阵骨骼动画形变
c语言·汇编·c++·python·硬件架构·游戏机
huang5791475 小时前
哈希算法的抗碰撞机制与安全性增强策略4
算法
林浩杨_5 小时前
SIGIR 2026|南京大学:Video-GAR:“通过生成 Query 来验证视频语义理解”的生成增强范式
论文阅读·人工智能·算法
Elsa️7466 小时前
算法一周刷题总结
c++·算法
风合星语6 小时前
2026 机器人工程实例(五):让 Allegro Hand 在 MuJoCo 中完成接触抓取——抓取状态机、稳定抬升与受控释放
c++·python·机器人·仿真