cunzai_zsy0531

关注我

CF1498D Bananas in a Microwave 题解

Post time: 2021-03-31 18:36:23

考虑直接模拟。开一个数组 \(f_i\) 表示第 \(i\) 个位置能够取到的时间,没有取到设为 \(-1\)。每一次的加或乘操作一步一步做即可。

以加法为例:设这一轮需要加的数为 \(x\),最多加的次数为 \(y\)。用一个数组 \(g_i\) 表示加到 \(i\) 这个数的次数。当 \(g_i=y\) 时,就不能用它继续往后加了。模拟过程是 \(O(m)\) 的,总复杂度 \(O(nm)\)

点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5+13;
int f[N],g[N],n,m,p=100000;
ll lim;
int main(){
	scanf("%d%d",&n,&m);lim=100000ll*m; //要注意对题目中给的x'i的操作,注意乘法会不会爆longlong。
	memset(f,-1,sizeof f);f[0]=0;
	for(int i=1;i<=n;++i){
		int op,y;ll x;
		scanf("%d%lld%d",&op,&x,&y);
		memset(g,0,sizeof g);
		for(int j=0;j<=m;++j){
			if(f[j]==-1||g[j]==y) continue;//特判这个位置能不能更新
			if(op==1){
				int tmp=(x-1)/p+1;
				if(j+tmp<=100000){
					if(f[j+tmp]==-1) f[j+tmp]=i,g[j+tmp]=g[j]+1;//注意这里的特判,因为如果f[j+tmp]已经更新过了,就不用更新g了
				}
			}
			else{
				if(j&&j*x<=lim){
					int tmp=(j*x-1)/p+1;
					if(f[tmp]==-1) f[tmp]=i,g[tmp]=g[j]+1;
				}
			}
		}
	}
	for(int i=1;i<=m;++i) printf("%d ",f[i]);
	return 0;
}
posted @ 2022-04-21 20:17  cunzai_zsy0531  阅读(14)  评论(0编辑  收藏  举报