求救,求救
查看原帖
求救,求救
182196
阿豆·克锐死停楼主2021/11/14 08:14

人已经爆炸了。 思路:

f i,j是i列j行的合法最优解,

g i,j 表示最优解的存在性,

fp i,j为上列经过连续跳跃到达的不一定最优的解。

用当前列的的f去刷下一列的f和fp表,用当前列的fp去刷当前列的fp和f

然鹅死了

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
inline long long r_ll(){
	long long f=1,x=0;int c;
	do{c=getchar();if(c=='-')f=-1;}while(c<'0'||c>'9');
	do{x=(x<<3)+(x<<1)+c-'0',c=getchar();}while(c>='0'&&c<='9');
	return f*x;
}
inline short int min(const short int &a,const short int &b){return a<b?a:b;}
inline short int min(const short int &a,const int &b){return a<b?a:b;}
inline short int min(const int &a,const short int &b){return a<b?a:b;}
inline short int min(const int &a,const int &b){return a<b?a:b;}
int n,m,k;
bool the_map[10010][1010];
short int f[10010][1010];
short int g[10010][1010];
int up[10010],dow[10010];
int pp[10010],ss[10010];
int ans=99999999;
short int fp[10010][1010];
inline bool check(int x){
	for(int i=1;i<=m;i++){
		if(g[x][i]) return 1;
	}
	return 0;
}

int main(){
	n=r_ll(),m=r_ll(),k=r_ll();
	for(int i=0;i<n;i++){
		up[i]=r_ll(),dow[i]=r_ll();
	}
	for(int i=0;i<=n;i++){
		for(int j=1;j<=m;j++){
			the_map[i][j]=1;
		}
	}
	for(int i=1;i<=k;i++){
		int x=r_ll(),y=r_ll(),z=r_ll();
		pp[x]=1;
		for(int j=1;j<=y;j++){
			the_map[x][j]=0;
		}
		for(int j=z;j<=m;j++){
			the_map[x][j]=0;
		}
	}
	for(int i=0;i<=n;i++){
		ss[i]=ss[i-1]+pp[i];
	}
	for(int i=1;i<=m;i++){
		g[0][i]=1;
	}
	for(int i=0;i<n;i++){
		for(int j=1;j<=m;j++){
			if(g[i][j]){
				int to1=(j-dow[i])<0?0:j-dow[i];
				int to2=(j+up[i]>m)?m:j+up[i];
				if(the_map[i+1][to1]){
					if(g[i+1][to1]){
						f[i+1][to1]=min(f[i+1][to1],f[i][j]);
					}else{
						f[i+1][to1]=f[i][j];
						g[i+1][to1]=1;
					}
					
				}
				if(the_map[i+1][to2]){
					if(g[i+1][to2]){
						f[i+1][to2]=min(f[i+1][to2],f[i][j]+1);
					}else{
						f[i+1][to2]=f[i][j]+1;
						g[i+1][to2]=1;
					}
				}
				if(fp[i+1][to2]){
					fp[i+1][to2]=min(fp[i+1][to2],f[i][j]+1);
				}else{
					fp[i+1][to2]=f[i][j]+1;
				}

			}
			if(i&&fp[i][j]){
				int to2=(j+up[i-1]>m)?m:j+up[i-1];
				if(fp[i][to2]){
					fp[i][to2]=min(fp[i][to2],fp[i][j]+1);
				}else{
					fp[i][to2]=fp[i][j]+1;
				}

				if(the_map[i][to2]){
					if(g[i][to2]){
						f[i][to2]=min(f[i][to2],fp[i][j]+1);
					}else{
						f[i][to2]=fp[i][j]+1;
						g[i][to2]=1;
					}
				}
			}
			if(i&&!check(i)){
				printf("0\n%d\n",ss[i-1]);
				return 0;
			}
		}
	}
	for(int j=1;j<=m;j++){
		if(fp[n][j]){
			int to2=(j+up[n]>m)?m:j+up[n-1];
			if(fp[n][to2]){
				fp[n][to2]=min(fp[n][to2],fp[n][j]+1);
			}else{
				fp[n][to2]=fp[n][j]+1;
			}
			if(the_map[n][to2]){
				if(g[n][to2]){
					f[n][to2]=min(f[n][to2],fp[n][j]+1);
				}else{
					f[n][to2]=fp[n][j]+1;
					g[n][to2]=1;
				}
			}
		}
	}
	for(int j=1;j<=m;j++){
		if(g[n][j]){
			ans=min(ans,f[n][j]);
		}
	}
	printf("1\n");
	printf("%d\n",ans);
	return 0;
}

2021/11/14 08:14
加载中...