2021年度训练联盟热身训练赛第八场

2021年度训练联盟热身训练赛第八场

原题pdf

A-Fire on Field

题意

构造数组,使得对于所有的 k   ( i − 2 k > 0 ) k \ (i - 2k > 0) k (i2k>0) 都有 a [ i ] − a [ i − k ] ! = a [ i − k ] − a [ i − 2 k ] a[i] - a[i - k] != a[i - k] - a[i - 2k] a[i]a[ik]!=a[ik]a[i2k] 。输出第 n n n 项。

思路

开始以为是有什么规律可循的构造,想了半天想不出,一看数据范围1e3,好直接暴力就行(

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

const int N = 1e6 + 10;

int a[N];
bool vis[N];

int main()
{
    int n;
    cin >> n;
    a[0] = a[1] = 1;
    for(int i = 2; i <= n; i++)
    {
        memset(vis, 0, sizeof(vis));
        for(int k = 1; i - 2 * k >= 0; k++)
        {
            vis[2 * a[i - k] - a[i - 2 * k]] = 1;
        }
        for(a[i] = 1; vis[a[i]]; a[i]++);
    }
    cout << a[n] << endl;
    return 0;
}

B-Gene Tree

题意

思路

代码

I-Thread Knots

题意

给定一串全部在x轴上的线,保证没有一条线完全包含另一条线,要求你用绳结把他们绑在一起,问所有绳结间距的最小值最大为多少

思路

二分枚举绳结的间距即可,挺签到的没人写,拿了个一血(

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;

struct node
{
    ll x;
    ll l;
    bool operator < (const node& obj) const
    {
        return x < obj.x;
    }
} a[N];

int n;

bool ok(ll len)
{
    ll now = a[0].x;
    for(int i = 1; i < n; i++)
    {
        now += len;
        if(now < a[i].x)
            now = a[i].x;
        else if(now > a[i].x + a[i].l)
            return 0;
    }
    return 1;
}

int main()
{
    scanf("%d", &n);
    ll l = INF, r = 0;
    for(int i = 0; i < n; i++)
    {
        scanf("%lld%lld", &a[i].x, &a[i].l);
        r = max(r, a[i].x + a[i].l);
        l = min(l, a[i].x);
    }
    r = r - l;
    l = 1;
    sort(a, a + n);
    ll ans;
    while(r >= l)
    {
        ll mid = (r + l) >> 1;
        if(ok(mid))
        {
            l = mid + 1;
            ans = mid;
        }
        else
            r = mid - 1;
    }
    printf("%lld\n", ans);
    return 0;
}

J-Triangulation

题意

对于 n n n 边形,你可以把它分成若干个三角形,定义两个三角形的距离为两个三角形中间间隔了多少三角形,给定 n n n ,求 n n n 边形分成若干三角形后,三角形间的最大距离的最小值是多少。

思路

可以发现最优解就是如下图的构造:

在这里插入图片描述

所以 n n n 边形的最大距离最小值就是 a n = ( a n + 1 ) / 2 + 2 a_n = (a_n + 1) / 2 + 2 an=(an+1)/2+2

代码

放个队友优美的代码(

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll dp[1000005];
int main(){
	int n;
	cin >> n;
	dp[4] = 1;
	for(int i = 5 ; i <= n ; i++)dp[i] = dp[(i + 1) / 2] + 2;
	cout << dp[n];
}

L-What’s Mine is Mine

题意

给定 m m m 种矿以及他们的价格和 n n n 次矿物出现时间(开始时间、结束时间、哪种矿物),一旦决定挖这种矿就必须从头到尾挖,并且一个时间只能挖一个矿,问最大收益。( ∑ i = s t a r t e n d ( p r i c e t ) = ( e n d − s t a r t ) ∗ p r i c e t \sum_{i = start}^{end}(price_t) = (end - start) * price_t i=startend(pricet)=(endstart)pricet

思路

简单dp,递推式如下:
d p e = m a x ( d p e , d p s + ( e − s ) ∗ p r i c e t ) dp_e = max(dp_e, dp_s + (e - s) * price_t) dpe=max(dpe,dps+(es)pricet)

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

const int N = 1e4 + 10;
const int M = 1e2 + 10;

int co[M];

struct node
{
    int s, e, t;
    bool operator < (const node& obj) const
    {
        if(s == obj.s)
            return e < obj.e;
        return s < obj.s;
    }
}a[N];

int dp[N];

int main()
{
    int m, n, ans = 0;
    cin >> m >> n;
    for(int i = 1; i <= m; i++)
    {
        cin >> co[i];
    }
    for(int i = 0; i < n; i++)
    {
        cin >> a[i].s >> a[i].e >> a[i].t;
    }
    sort(a, a + n);
    for(int i = 0; i < n; i++)
    {
        int e = a[i].e;
        int s = a[i].s;
        int t = a[i].t;
        for(int i = 0; i < s; i++)
            dp[s] = max(dp[s], dp[i]);
        dp[e] = max(dp[e], dp[s] + (e - s) * co[t]);
        ans = max(ans, dp[e]);
    }
    cout << ans << endl;
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值