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;
}