noip2014day1t3

dp(多重背包加01背包加优化)

#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
const int inf=100000000;
const int maxn=1000+10;
int n,m,k,ans,cnt,p;
int up[maxn],down[maxn],x[maxn],y[maxn],f[maxn][1010];
template <class T> void read(T&x)
{
  x=0;char c=getchar();int f=0;
  while(c>'9'||c<'0'){f|=(x=='-');c=getchar();}
  while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
  x=f?-x:x;
}
int main()
{
  freopen("bird.in","r",stdin);
  freopen("bird.out","w",stdout);
  read(n);read(m);read(k);
  up[n]=m+1;down[n]=0;
  for(int i=0;i<n;i++)
  {
      read(x[i]);read(y[i]);
      up[i]=m+1;down[i]=0;
  }
  for(int i=1;i<=k;i++){read(p);read(down[p]);read(up[p]);}
  for(int i=1;i<=n;i++)
   for(int j=0;j<=m;j++)
    f[i][j]=inf;f[0][0]=inf;
  for(int i=1;i<=n;i++)
  {
      for(int j=x[i-1];j<=m;j++)f[i][j]=min(f[i][j],min(f[i-1][j-x[i-1]]+1,f[i][j-x[i-1]]+1));
      for(int j=m-x[i-1];j<=m;j++)f[i][m]=min(f[i][m],min(f[i-1][j]+1,f[i][j]+1));
      for(int j=down[i]+1;j<=up[i]-1;j++)if(j+y[i-1]<=m)f[i][j]=min(f[i][j],f[i-1][j+y[i-1]]);
      for(int j=1;j<=down[i];j++)f[i][j]=inf;
      for(int j=up[i];j<=m;j++)f[i][j]=inf;
  }
  ans=inf,cnt=k;
  for(int i=n;i>=1;i--)
  {
    for(int j=down[i]+1;j<=up[i]-1;j++)ans=min(ans,f[i][j]);
    if(ans!=inf)break;if(up[i]!=m+1)cnt--;
  }
  if(cnt==k)printf("1\n%d",ans);
  else printf("0\n%d",cnt);
  fclose(stdin);fclose(stdout);
  return 0;
}
View Code

 

posted @ 2017-10-23 18:12  新手-周  阅读(131)  评论(0编辑  收藏  举报