Luogu - 春季多校集训营 (五)

F题 解题思路:


我是真的傻,原先好久没想明白这题

给予a , n1 , n2 三个数值,其中 n1, n2已经给出,求满足式子有多少种情况,其中如果 (a + b) > 2^31 那么结果就是 a + b - 2 ^ 32。

对于 a + n1 > n2的情况: 答案为 2147483647 - n2,
对于 a + n1 < n2的情况:那么答案为 2147483648 - n2

证明:(对第一种情况)

收先我们将 式子化为 a > n2 - n1, 所以满足情况的为2147483647 - n2 + n1, 然后想到超过 2147483647,那么在最后面肯定是会有 n1 的,所以符合条件的为2147483647 - n2。

代码:
#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

long long  r = 2147483647, l = 2147483648;

int main(){
    long long   n, m;
    char st,a;
    scanf("%c+%lld%c%lld",&a,&n,&st,&m);
    if (st == '>'){
        printf("%lld", r - m);
    }
    else{
        printf("%lld",l + m);
    }
    return 0;
}

A题 解题思路:


首先如果m > n * b ,那么肯定输出 no, 然后我们考虑 将 一个 b 分成 0 - b/2 (因为2个的话可以书写完整的区间,而一个的话只能显示一半),然后我们再考虑化成 a,考虑 (b * n - m)% (b - a) ,如果% 为 0,那么我们判断(b * n - m) % (b - a) 是否大于 n, 如果大于 n 那么肯定无解,如果 <= n,那么存在有解的情况,其他都是无解。

注意: 这里注意0的情况,而且要开 __int128。


代码:
#include <iostream>
#include <stdio.h>
#include <cstring>

using namespace std;

int main(){
    int t;
    scanf("%d",&t);
    for (int i = 0; i < t; i++){
        long long n, m, a, b;
        scanf("%lld%lld%lld%lld",&n,&m,&a,&b);
        if( n == 0 )
			if( m == 0 ) puts( "Yes" );
			else puts( "No" );
		else{
			if( ( ( __int128 ) ( n - 1 ) ) * b + b / 2 >= m ) puts( "Yes" );
			else if( ( ( ( __int128 ) n ) * b - m ) < 0 ) puts( "No" );
			else if( ( ( ( __int128 ) n ) * b - m ) % ( b - a ) == 0 ){
				if( ( ( ( __int128 ) n ) * b - m ) / ( b - a ) <= n ) puts( "Yes" );
				else puts( "No" );
			}
			else puts( "No" );
		}
    }
    return 0;
}


G题 解题思路:


dp问题, 到目前为止我的dp还很菜,这段时间抓紧时间补一下。

这个就是种情况,一种是添加个空格,花费 r ,另一种是匹配,如果相同那么加 α,如果不同就减β,因此我们dp 求选上面的点还是下面的点(不选的填空格,也就是 - r),还有直接匹配,如果可以匹配,那么加α,如果不能减β。最后求最终状态的值。


代码:
#include <iostream>
#include <stdio.h>
#define MAXN 5010

using namespace std;

int n , m , alpha , beta , gamma;
long long f[ MAXN ][ MAXN ];
char a[ MAXN ] , b[ MAXN ];

int main()
{
	cin >> n >> m >> alpha >> beta >> gamma >> a + 1 >> b + 1;
	for( int i = 1 ; i <= n || i <= m ; i++ )
		f[i][0] = f[0][i] = - i * 1ll * gamma;
	for( int i = 1 ; i <= n ; i++ )
		for( int j = 1 ; j <= m ; j++ )
			f[i][j] = max( max( f[i - 1][j] , f[i][j - 1] ) - gamma , f[i - 1][j - 1] + ( a[i] == b[j] ? alpha : -beta ) );
	cout << f[n][m] << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值