随笔 - 72,  文章 - 2,  评论 - 0,  阅读 - 1258

P8742 [蓝桥杯 2021 省 AB] 砝码称重

题意:n个砝码,砝码的大小是a[i],问可以称量多少个不同大小的物品;

思路:运用DP,dp[j]是j重量的能否被称量;

代码:

#include<bits/stdc++.h>
using namespace std;
int dp[101][100001],n,s,a[105];
int main(){
    cin>>n;
    for (int i = 1; i <=n ; ++i) {
        cin>>a[i];
        dp[i][a[i]]=1;
        s+=a[i];
    }
    for (int i = 1; i <=n ; ++i) {
        for (int j = s; j >=0 ; --j) {
            if(dp[i-1][j]){
                dp[i][j]=dp[i][j+a[i]]=dp[i][abs(j-a[i])]=1;
            }
        }
    }
    int cnt=0;
    for (int i = 1; i <=s ; ++i) {
        if(dp[n][i])
            cnt++;
    }
    cout<<cnt;
}

P8755 [蓝桥杯 2021 省 AB2] 负载均衡

题意:有n台计算机,m个任务,n台计算机的算力分别是v[i],每个任务开始于a,用到b号计算机,持续c秒,占用算力是d,问每一个任务能否完成,若可以,输出剩余算力

思路:用优先队列维护每一个机器的正在里面的任务,若不能加入,则-1,若能加入,则输出v【i】-d

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
    int n,m;
    cin>>n>>m;
    vector<ll>v;
    for (int i = 0; i <n ; ++i) {
        ll x;
        cin>>x;
        v.push_back(x);
    }
    vector<priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>>>que(n);
    for (int i = 0; i <m ; ++i) {
        ll a,b,c,d;
        cin>>a>>b>>c>>d;
        b--;
        while (que[b].size()&&que[b].top().first<=a)v[b]+=que[b].top().second,que[b].pop();
        if(v[b]<d){
            cout<<"-1\n";
            continue;
        }
        v[b]-=d;
        que[b].emplace(a+c,d);
        cout<<v[b]<<endl;
    }

}

P8749 [蓝桥杯 2021 省 B] 杨辉三角形

题意:杨辉三角,问a最早出现是在第几个数

思路:

杨辉三角左右完全对称,所以答案一定是在左半边。

我们侧着看每一个斜行内一定是单调递增的,且斜行之间也一定是单调递增的。比如第三斜行的第一个数6在第二斜行总出现的位置一定是更靠后,为什么?因为第三斜行的6所在的横放是1,4,6,所以对应的第二斜行的位置是4,所以6在第二斜行出现一定更靠后。

且第k斜行的数是Ck(2k),C(k+1)2k,C(k+2)2k⋯,所以在斜行内可以二分。并且CC(17)34>1e9,所以数字一定出现在前16个斜行中。我们直接在每一个斜行中二分即可。复杂度 O(logn)

代码:

# include <bits/stdc++.h>

using namespace std;

#define int long long

int n;

int C(int x, int y) {
    y = min(y, x - y);
    int res = 1;
    for (int i = x, j = 1; j <= y; i--, j++){
        res = res * i / j;
        if( res > n ) return res;
    }
    return res;
}

int check( int k ){
    int l = k * 2 , r = max( n , l ) , mid , res ;
    while( l <= r ){
        mid = ( l + r ) >> 1;
        if( C( mid , k ) >= n ) res = mid , r = mid - 1;
        else l = mid + 1;
    }
    if( C(res,k) != n ) return -1;
    return  ( 1 + res ) * res / 2 + k + 1 ;
}

int32_t main() {
    cin >> n;
    for( int i = 16 , t ; ; i -- ){
        t = check(i);
        if( t == -1 ) continue;
        cout << t;
        return 0;
    }
    return 0;
}
posted on   IR101  阅读(32)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示