1. 程式人生 > 其它 >【ABC】153題解

【ABC】153題解

傳送門:https://atcoder.jp/contests/abc153/tasks

A

向上取整

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

int main(){
	int a, b; cin>>a>>b;
	cout<<(a+b-1)/b;
	return 0;
}

B

判斷全部法術用一次能不能幹掉

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

int main(){
	int k, n; cin>>k>>n;
	while(n--){
		int t; cin>>t;
		k-=t;
	}
	puts(k<=0? "Yes": "No");
	return 0;
}

C

向耗費最高的 \(k\) 個怪物施即死咒。

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

#define int long long

const int N=2e5+5;
int w[N];

signed main(){
	int n, k; cin>>n>>k;
	
	for(int i=0; i<n; i++) cin>>w[i];
	sort(w, w+n);
	
	int res=0;
	for(int i=0; i<n-k; i++) res+=w[i];
	cout<<res<<endl;
	
	return 0;
}

D

遞迴+記憶化

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

#define int long long

map<int, int> f;

int cal(int v){
	if(f[v]) return f[v];
	return f[v]=1+cal(v/2)+cal(v/2);
}

signed main(){
	f[1]=1;
	int h; cin>>h;
	cout<<cal(h)<<endl;
	
	return 0;
}

E

\(f[i]\) 表示斬殺血量為 \(i\)

的怪物最少花費,轉化為完全揹包問題。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=1005, M=10005;

int h, n;
int w[N], v[N];
int f[M];

int main(){
	read(h), read(n);
	rep(i,1,n) read(v[i]), read(w[i]);
	
	memset(f, 0x3f, sizeof f);
	f[0]=0;
	rep(i,1,n) rep(j,0,h) f[j]=min(f[max(0, j-v[i])]+w[i], f[j]);
	cout<<f[h]<<endl;
	
    return 0;
}

F

將怪物按照座標排序,策略是:從左到右列舉怪物並且依次擊殺。
需要維護的資訊是其他怪物受到的濺射傷害,需要查詢的資訊是當前怪物的血量,於是我們可以建一棵線段樹維護。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

#define int long long

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=2e5+5;

int n, d, a;
struct node{
	int p, h;
	bool operator < (const node &o)const{
		return p<o.p;
	}
}e[N];

int w[N], pos[N];

struct Tree{
	int l, r;
	int sum, sub;
}tr[N<<2];

int ls(int u){return u<<1;}
int rs(int u){return u<<1|1;}

void pushup(int u){
	tr[u].sum=tr[ls(u)].sum+tr[rs(u)].sum;
}

void build(int u, int l, int r){
	tr[u]={l, r};
	if(l>=r){
		tr[u].sum=w[l];
		return;
	}
	int mid=l+r>>1;
	build(ls(u), l, mid), build(rs(u), mid+1, r);
	pushup(u);
}

void pushdown(int u){
	auto &L=tr[ls(u)], &R=tr[rs(u)];
	L.sum-=tr[u].sub*(L.r-L.l+1), L.sub+=tr[u].sub;
	R.sum-=tr[u].sub*(R.r-R.l+1), R.sub+=tr[u].sub;
	tr[u].sub=0;
}

void modify(int u, int l, int r, int k){
	if(l<=tr[u].l && tr[u].r<=r){
		tr[u].sum-=(tr[u].r-tr[u].l+1)*k;
		tr[u].sub+=k;
		return;
	}
	pushdown(u);
	int mid=tr[u].l+tr[u].r>>1;
	if(l<=mid) modify(ls(u), l, r, k);
	if(mid<r) modify(rs(u), l, r, k);
	pushup(u);
}

int query(int u, int p){
	if(tr[u].l==tr[u].r && tr[u].l==p) return tr[u].sum;
	int mid=tr[u].l+tr[u].r>>1;
	int res=0;
	pushdown(u);
	if(p<=mid) res=query(ls(u), p);
	else res=query(rs(u), p);
	return res;
}

signed main(){
	read(n), read(d), read(a);
	rep(i,1,n) read(e[i].p), read(e[i].h), e[i].h=ceil(e[i].h, a);
	int len=d<<1;
	
	sort(e+1, e+1+n);
	
	rep(i,1,n) w[i]=e[i].h, pos[i]=e[i].p/*, debug(pos[i])*/;
	build(1, 1, n);
	
	int res=0;
	rep(i,1,n){
		// debug(query(1, i));
		if(query(1, i)<=0) continue;
		int L=i, R=upper_bound(pos+L, pos+n+1, pos[L]+len)-pos-1;
		// debug(R);
		// debug(query(1, L));
		res+=query(1, L), modify(1, L, R, query(1, L));
	}
	
	// rep(i,1,n) debug(query(1, i));
	cout<<res<<endl;
	
    return 0;
}