f [ i ] [ j ] 表示横坐标为 i ,高度为 j 时的最小点击次数
分别dp处理:
1.上升,(1)<m
(2)>=m
2.下降
3.管道
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 const int N=10010,M=1010; 5 const int INF=1010000; 6 int n,m,k,f[N][M],up[N],down[N],l[N],h[N],flag[N]; 7 int min(int x,int y){ 8 return x<y?x:y; 9 } 10 void print(int x){ 11 int sum=0; 12 for (int i=0;i<x;i++) 13 if (flag[i]) 14 sum++; 15 printf("0\n%d",sum); 16 } 17 int main(){ 18 int x,y,p; 19 scanf("%d %d %d",&n,&m,&k); 20 for (int i=1;i<=n;i++){ 21 scanf("%d %d",&x,&y); 22 up[i]=x; 23 down[i]=y; 24 } 25 for (int i=0;i<=n;i++){ 26 h[i]=m+1; 27 l[i]=0; 28 flag[i]=0; 29 } 30 for (int i=1;i<=k;i++){ 31 scanf("%d %d %d",&p,&x,&y); 32 h[p]=y; 33 l[p]=x; 34 flag[p]=1; 35 } 36 for (int i=1;i<=n;i++) 37 for (int j=1;j<=m;j++) 38 f[i][j]=INF; 39 for (int j=1;j<=m;j++) 40 f[0][j]=0; 41 for (int i=1;i<=n;i++){ 42 for (int j=up[i]+1;j<=m;j++){ 43 f[i][j]=min(f[i][j],min(f[i][j-up[i]],f[i-1][j-up[i]])+1); 44 }//up<m 45 for (int j=m-up[i];j<=m;j++) 46 f[i][m]=min(f[i][m],min(f[i-1][j],f[i][j])+1);//^up>=m 47 for (int j=1;j<=m-down[i];j++) 48 f[i][j]=min(f[i][j],f[i-1][j+down[i]]);//down 49 for (int j=h[i];j<=m;j++)//shangjie 50 f[i][j]=INF; 51 for (int j=1;j<=l[i];j++)//xiajie 52 f[i][j]=INF; 53 int judge=0; 54 for (int j=1;j<=m;j++)//check 55 if (f[i][j]<INF) 56 judge=1; 57 if (!judge){ 58 print(i); 59 return 0; 60 } 61 } 62 int ans=INF; 63 for (int j=1;j<=m;j++) 64 ans=min(ans,f[n][j]); 65 printf("1\n%d",ans); 66 return 0; 67 }