- gcdsum
这一题注意又stl agorithm 库里面的现成函数 __gcd(a,b)可以使用
#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算法先填最大的,可以这样思考如果填当前最大的不是最优解,那么填一个较小的数就是最优解,那么为了放这个最大数,如果较小的数原来应该在的位置可以放下那么开销不会增加如果无法放下那麽就要增加开销。因此先放最大的数不会破坏最优解。
#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+b−1],其二,这里实际上利用了队列的思想,类似于层序遍历。
其三,注意剪枝。