2024-10-31-solution-p7070

P7070 [NWRRC2014] Kebab House 题解

模拟赛题,小清新吧。

这里是一份 O(nq2)O(n q^2) 的垃圾题解。

首先我们可以直接设 fi,j,kf_{i,j,k} 表示前 ii 分钟学了 jj 分钟上一次摸鱼是在 kk 分钟前。直接摁做是 O(nq2t)O(n q^2 t) 的。

不难注意到其实 j>i(it)j > i - (i \over t) 所以复杂度直接就对了!

点击查看代码
// Problem: P7070 [NWRRC2014] Kebab House
// URL: https://www.luogu.com.cn/problem/P7070
// Writer: WRuperD
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int mininf = 1e9 + 7;
// #define int long long
#define pb emplace_back
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void write(int x){if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');}
#define put() putchar(' ')
#define endl puts("")
const int MAX = 2e3 + 10;
const int MAX2 = 305;

int f[2][MAX2][205];
int g[MAX2];

int mod;

inline int Mod(int x){
	if(x >= mod)	return x - mod;
	return x;
}

void solve(){
	// int n = 2000, t = 200;
	int n = read(), t = read();
	mod = 1e9 + 7;
	f[0][0][t + 1] = 1;
	if(t == 0){
		while(n--){
			int x = read(), y = read();
			for(int i = 1; i <= x; i++){
				for(int j = 0; j <= i; j++){
					for(int k = 1; k <= t + 1; k++){
						f[i & 1][j][k] = 0;
					}
				}
				for(int j = 0; j <= i; j++){
					for(int k = 1; k <= t + 1; k++){
						if(j) f[i & 1][j][k] = Mod(f[i & 1 ^ 1][j - 1][k] + f[i & 1 ^ 1][j][k]);
						else f[i & 1][j][k] = f[i & 1 ^ 1][j][k];
					}
				}
			}
			for(int i = 1; i <= t + 1; i++)	g[i] = 0;
			for(int j = y; j <= x; j++){
				for(int k = 1; k <= t + 1; k++){
					g[k] = Mod(g[k] + f[x & 1][j][k]);
				}
			}
			
			for(int j = 0; j <= x; j++)	for(int k = 1; k <= t + 1; k++)	f[0][j][k] = f[1][j][k] = 0;
			// write(f[x % 2][x][t + 1]), endl;
			for(int i = 1; i <= t + 1; i++)	f[0][0][i] = g[i];
			// for(int i = 1; i <= t + 1; i++)	write(g[i]), put();
			// endl;
			// for(int i = 1; i <= )
		}
		int ans = 0;	
		// write(f[0][0])
		for(int i = 1; i <= t + 1; i++){
			ans = Mod(ans + f[0][0][i]);
		}
		write(ans), endl;
		return ;
	}
	while(n--){
		// int x = 300, y = 300;
		int x = read(), y = read();
		for(int i = 1; i <= x; i++){
			for(int j = max(0, (i - 2) - (i - 2) / max(1, t) - 1); j <= i; j++){
				for(int k = 1; k <= t + 1; k++){
					f[i & 1][j][k] = 0;
				}
			}
			for(int j = max(0, i - i / max(1, t) - 1); j <= i; j++){
				for(int k = 1; k <= t + 1; k++){
					if(k == 1){
						f[i & 1][j][k] = f[i & 1 ^ 1][j][t + 1];
					}else{
						if(k == t + 1){
							if(j) f[i & 1][j][k] = Mod(f[i & 1 ^ 1][j - 1][k] + f[i & 1 ^ 1][j - 1][k - 1]);
							else f[i & 1][j][k] = 0;
						}else{
							if(j) f[i & 1][j][k] = f[i & 1 ^ 1][j - 1][k - 1];
							else f[i & 1][j][k] = 0;
						}	
					}
				}
			}
		}
		for(int i = 1; i <= t + 1; i++)	g[i] = 0;
		for(int j = max(y, x - x / max(1, t) - 1); j <= x; j++){
			for(int k = 1; k <= t + 1; k++){
				g[k] = Mod(g[k] + f[x & 1][j][k]);
			}
		}
		
		for(int j = max(0, x - 2 - (x - 2) / max(1, t) - 1); j <= x; j++)	for(int k = 1; k <= t + 1; k++)	f[0][j][k] = f[1][j][k] = 0;
		// write(f[x % 2][x][t + 1]), endl;
		for(int i = 1; i <= t + 1; i++)	f[0][0][i] = g[i];
		// for(int i = 1; i <= t + 1; i++)	write(g[i]), put();
		// endl;
		// for(int i = 1; i <= )
	}
	int ans = 0;	
	// write(f[0][0])
	for(int i = 1; i <= t + 1; i++){
		ans = Mod(ans + f[0][0][i]);
	}
	write(ans ), endl;
}

signed main(){
	// freopen("homework.in", "r", stdin);
	// freopen("homework.out", "w", stdout);
	int t = 1;
	while(t--)	solve();
	return 0;
}