CodeForces - 1498D Bananas in a Microwave(思维+dp)
Posted Frozen_Guardian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1498D Bananas in a Microwave(思维+dp)相关的知识,希望对你有一定的参考价值。
题目链接:点击查看
题目大意:给出 n n n 次操作,初始时有一个 k = 0 k=0 k=0,每次操作抽象为三个数 t x y t\\ x\\ y t x y,其中 x x x 可能为小数,可以选择一个 n u m ∈ [ 0 , y ] num\\in[0,y] num∈[0,y],使得:
- t = 1 t=1 t=1:执行 n u m num num 次 k = ⌈ ( k + x ) ⌉ k=\\lceil (k+x) \\rceil k=⌈(k+x)⌉
- t = 2 t=2 t=2:执行 n u m num num 次 k = ⌈ ( k ∗ x ) ⌉ k=\\lceil (k*x) \\rceil k=⌈(k∗x)⌉
问对于 [ 1 , m ] [1,m] [1,m] 的每个数,最少可以通过多少次操作获得,如果无法获得输出 − 1 -1 −1
题目分析:读完题第一反应感觉是 b f s bfs bfs,但时间复杂度是 O ( n ∗ m ∗ m ) O(n*m*m) O(n∗m∗m) 级别的,因为一共有 n ∗ m n*m n∗m 个状态,每个状态又可以扩展出 m m m 次,所以显然是不可行的
看了题解后,发现这个模型也可以视为 01 01 01 背包问题,其中,有 n ∗ m n*m n∗m 个物品,背包容量是 m m m,如果直接暴力的话复杂度显然也是 O ( n ∗ m ∗ m ) O(n*m*m) O(n∗m∗m) 的
不过对于本题而言,有一个很重要的性质,也就是如果某个容量 u u u 可以扩展到 v v v ,且 v v v 之前已经被更新过的话,那么就可以直接 b r e a k break break 了,分两种情况举例一下就明白了:
- 假设 u + t = v u+t=v u+t=v,那么 v + 1 v+1 v+1 状态,可以从 u + t + 1 u+t+1 u+t+1 更新,也可以从 v + 1 v+1 v+1 更新
- 假设 u ∗ t = v u*t=v u∗t=v,那么 v ∗ t v*t v∗t 状态,可以从 u ∗ t 2 u*t^2 u∗t2 更新,也可以从 v ∗ t v*t v∗t 更新
所以综上所述,每个状态至多被更新一次,及时剪枝的话时间复杂度实际上是 O ( n ∗ m ) O(n*m) O(n∗m) 的
代码:
// Problem: D. Bananas in a Microwave
// Contest: Codeforces - CodeCraft-21 and Codeforces Round #711 (Div. 2)
// URL: https://codeforces.com/contest/1498/problem/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
T f=1;x=0;
char ch=getchar();
while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=f;
}
template<typename T>
inline void write(T x)
{
if(x<0){x=~(x-1);putchar('-');}
if(x>9)write(x/10);
putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e5+100;
const int base=1e5;
bool dp[210][N];
LL t,x,y;
int ans[N];
void update(LL &cur) {
if(t==1) {
cur=cur+(x+base-1)/base;
} else {
cur=(cur*x+base-1)/base;
}
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
int n,m;
memset(ans,-1,sizeof(ans));
read(n),read(m);
dp[0][0]=true;
for(int i=1;i<=n;i++) {
read(t),read(x),read(y);
for(int j=0;j<=m;j++) {
dp[i][j]=dp[i-1][j];
}
for(int j=0;j<=m;j++) {
if(!dp[i-1][j]) {
continue;
}
LL pos=j;
for(int t=1;t<=y;t++) {
update(pos);
if(pos>m||dp[i-1][pos]) {
break;
}
dp[i][pos]=true;
ans[pos]=i;
}
}
}
for(int i=1;i<=m;i++) {
printf("%d ",ans[i]);
}
return 0;
}
以上是关于CodeForces - 1498D Bananas in a Microwave(思维+dp)的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Banana 在 JavaScript 中打印? [复制]