不难又挺有收获的一个线性dp...细节很多~很好的一个dp题
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N=10002,M=2005;
bool vis[N];//表示这个点有没有管道.
int x[N],y[N];//可以上升多少 可以下降多少
int l[N],h[N];//最低点 最高点.
int f[N][M];//表示到了i,最少需要按多少次才能到j的高度.
int main()
{
    int n,m,k,a,b,c;
    cin>>n>>m>>k;//m是高度.
    for(int i=1;i<=n;i++)
    {
        cin>>a>>b;
        x[i]=a;y[i]=b;
        l[i]=1;h[i]=m;//可通过的.
    }
    for(int i=1;i<=k;i++)
    {
        cin>>c>>a>>b;
        l[c]=a+1;
        h[c]=b-1;
        vis[c]=true;
    }
    memset(f,0x3f,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<=m+x[i];j++)
       {
           f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);
       }
       for(int j=m+1;j<=m+x[i];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<l[i];j++) f[i][j]=f[0][0];
       for(int j=h[i]+1;j<=m;j++) f[i][j]=f[0][0];
    }
    int ans=f[0][0];
    for(int i=1;i<=m;i++) ans=min(ans,f[n][i]);
    if(ans<f[0][0]) printf("1\n%d\n",ans);
    else
    {
        int cnt=0;
        int i,j;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(f[i][j]<f[0][0]) break;
            }
            if(j==m+1) break;
            if(vis[i])  cnt++;
        }
        printf("0\n%d\n",cnt);
    }
    return 0;
}