人已经爆炸了。 思路:
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;
}