提交时间:2024-07-03 13:44:53
运行 ID: 153498
#include<bits/stdc++.h> using namespace std; int n,m,k,x[10005],y[10005],low[10005],high[10005],f[10005][2005],ans=0x3f3f3f; bool flag[10005]; int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]); for(int i=1;i<=n;i++){ high[i]=m;//初始最高能到m low[i]=1;//初始最低能到1 } for(int i=1,P,L,H;i<=k;i++){ scanf("%d%d%d",&P,&L,&H); flag[P]=1; low[P]=L+1;//注意下沿高度要加1 high[P]=H-1;//注意上沿高度要减1 } memset(f,0x3f3f3f,sizeof(f)); for(int i=1;i<=m;i++)f[0][i]=0; for(int i=1;i<=n;i++){//向右出发 for(int j=x[i]+1;j<=x[i]+m;j++)f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);//上升这一段,完全背包;前一单位跳或现在跳 for(int j=m+1;j<=x[i]+m;j++)f[i][m]=min(f[i][m],f[i][j]);//飞出了天花板的特殊情况 for(int j=1;j<=m-y[i];j++)f[i][j]=min(f[i][j],f[i-1][j+y[i]]);//下降这一段 for(int j=1;j<low[i];j++)f[i][j]=0x3f3f3f;//处理无法通过的地方 for(int j=high[i]+1;j<=m;j++)f[i][j]=0x3f3f3f; } for(int i=1;i<=m;i++)ans=min(ans,f[n][i]); if(ans<0x3f3f3f)printf("1\n%d",ans);//若能通过,直接输出答案 else{ ans=0; for(int i=1;i<=n;++i)for(int j=1;j<=m;++j) if(flag[i]&&f[i][j]<0x3f3f3f){ ans++; break; } printf("0\n%d",ans); } return 0; }