noip飞扬的小鸟

题解:

挺简单的题目

f[i][j]表示x坐标为i,y坐标为j的最小值

会发现那个东西是个完全背包

从f[i][j-a[i]]转移一下就是O(1)转移的了

另外上界为m这个要特判一下

我把sum[a[i]]写成了sum[i]还过了样例拿了65分真的是神奇

另外注意一下要先计算再判断不可行的

因为他是在前一格瞬间跳到那么高

代码:

 

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const int N=2e4;
int f[2][2000],n,m,k,a[N],b[N],sum[N],t[N][2];
struct re{
  int a,b,c;
}c[N];
const int INF=1e9;
void minn(int &x,int y)
{
  if (x>y) x=y;
}
int main()
{
  ios::sync_with_stdio(false);
  cin>>n>>m>>k;
  rep(i,1,n) cin>>a[i]>>b[i];
  rep(i,1,k) cin>>c[i].a>>c[i].b>>c[i].c,c[i].b++,c[i].c--;
  rep(i,1,n) t[i][0]=1,t[i][1]=m;
  rep(i,1,k) t[c[i].a][0]=c[i].b,t[c[i].a][1]=c[i].c,sum[c[i].a]=1;
  rep(i,1,n) sum[i]+=sum[i-1];
  f[0][0]=INF;
  rep(i,1,n) 
  {
    rint now=i%2,lst=(i+1)%2;
    rep(j,1,m) f[now][j]=INF;
    rep(j,a[i]+1,m) minn(f[now][j],min(f[now][j-a[i]],f[lst][j-a[i]])+1);
    rep(j,m-a[i],m) minn(f[now][m],min(f[now][j],f[lst][j])+1);
    rep(j,1,m) 
      if (j+b[i]<=m) minn(f[now][j],f[lst][j+b[i]]);
    rep(j,0,t[i][0]-1) f[now][j]=INF;
    rep(j,t[i][1]+1,m) f[now][j]=INF;
    bool tt=1;
    rep(j,1,m) if (f[now][j]<INF) tt=0;
    if (tt)
    {
      cout<<0<<endl;
      cout<<sum[i]-1;
      exit(0);
    }
  }
  cout<<1<<endl;
  int ans=INF;
  rep(i,1,m) minn(ans,f[n%2][i]);
  cout<<ans<<endl;
  return 0;
}

 

posted @ 2018-08-21 12:11  尹吴潇  阅读(173)  评论(0编辑  收藏  举报