codefoece 711

  1. gcdsum

这一题注意又stl agorithm 库里面的现成函数 __gcd(a,b)可以使用

Problem - B - Codeforces

#include <bits/stdc++.h>
using namespace  std;
typedef long long ll;
#define f(i,n) for(int i=0;i<n;i++)
ll a[100005];
ll b[100005];
bool cmp(ll x,ll y){return x>y;}
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n, w;
        ll ans = 0;
        cin >> n >> w;
        f(i,n)
        {
            cin >> a[i];
        }
        sort(a,a+n,cmp);
        f(i,n) b[i] = w;
        f(i,n)
        {
            ll* index = lower_bound(b,b+n,a[i]);
            *index -= a[i];
            ans = index - b + 1 > ans ? index - b + 1 : ans;
        }
        cout << ans <<endl;
    }

    return 0;
}

这道题使用greety算法先填最大的,可以这样思考如果填当前最大的不是最优解,那么填一个较小的数就是最优解,那么为了放这个最大数,如果较小的数原来应该在的位置可以放下那么开销不会增加如果无法放下那麽就要增加开销。因此先放最大的数不会破坏最优解。

Problem - D - Codeforces

#include <bits/stdc++.h>
#define f(i,n) for(int i=0;i<n;i++)
#define ms(a,x,l) for(int i=0;i<=l;i++) a[i] = x;
#define IO    ios::sync_with_stdio(false);cin.tie(0);
const long long inf = 0x3f3f3f3f3f3f3f3fLL;
// const double inf = 2e9;
const int N = 2e5 + 10;
//const long long MOD = 1e9 + 7;
// const int MOD = 998244353;
const int D = 1e5;
typedef long long ll;
#define gpq priority_queue <int,vector<int>,greater<int> >;
//降序队列
#define lqp priority_queue <int,vector<int>,less<int> >;
//降序
using namespace std;
bool cmp(ll x,ll y){return x>y;}
ll ceil(ll a, ll b){
    return (a + b - 1) / b;
}

void op(ll  t, ll  x, ll &c){
    if(t == 1)
        c = c + ceil(x, D);
    else
        c = ceil(c * x, D);
}

int main() {

    IO
    int n,m,t,x,y;
    cin >> n >> m;
    vector<bool> vis(m + 1);
    vis[0] = 1;
    vector<int> ans(m + 1, -1);
    ans[0] = 0;
    f(i,n)
    {
        cin >> t >> x >>y;
        //这里必须是同一类型的才可以
        vector <bool> visc = vis;
        f(j,m+1)
        {
            if(vis[j]){
                ll cur = j;
                op(t,x,cur);
                f(k,y){
                    if(cur > m) break;
										//会在下一次扩展中重新计算,所以要剪枝。
                    if(vis[cur]) break;
                    ans[cur] = i + 1;
                    visc[cur] = 1;
                    op(t,x,cur);
                }
            }
        }
        vis = visc;
    }
    f(i,m+1) if(i) cout<<ans[i]<<" ";
    return 0;
}

一个是先下取整的技巧 ⌈ a b ⌉   = [ a + b − 1 b ] \lceil \frac{a}{b}\rceil\ = [\frac{a+b-1}{b}] ba =[ba+b1],其二,这里实际上利用了队列的思想,类似于层序遍历。

其三,注意剪枝。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值