LOJ2500 NOIP2014 flying birds [backpack DP]*

Posted by Frank H. Shaw on Tue, 31 Dec 2019 10:18:34 +0100

LOJ2500 NOIP2014 flying birds

LINK

The main idea of the topic is that there are n columns. You can choose not to lower the height y and increase x * px * p every second. If the current position plus x * px * P is greater than the upper bound m, it will stop at M.
If you can successfully cross all columns, output the minimum number of clicks, otherwise output the maximum number of columns you can cross

The feeling is very obvious DP. If you don't click, it's a 01 knapsack. When you click, it's a complete knapsack
Therefore, it can be set that dp[i][j]dp[i][j] is the minimum number of steps to reach the height of column I of j

And then you can find the transfer
dp[i][j]=min(dp[i−1][j−x[i]∗p]+p)dp[i][j]=min(dp[i−1][j−x[i]∗p]+p)
It's like this when it's falling down
dp[i][j]=dp[i−1][j+y[i]]dp[i][j]=dp[i−1][j+y[i]]
And then when it comes to complete backpacking, it can become a contribution that only considers one click at a time and then adds all the contributions

Then, it should be noted that the influence factors of the lower bound cannot be considered when the backpack is completely transferred, because the next pillar is not reached by default when the backpack is transferred
Finally, after the transfer, add the influence of the lower bound

And then it's down. It's up. It's up

#include<bits/stdc++.h>
using namespace std;
#define M 1010
#define N 10010
#define INF 0x3f3f3f3f
int dp[2][N],ind=0;
int n,m;
int k,p[N],l[N],r[N];
int x[N],y[N];
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<=k;i++){
        int p,ll,rr;
        scanf("%d%d%d",&p,&ll,&rr);
        l[p]=ll+1;r[p]=rr-1;
    }
    for(int i=1;i<=n;i++)if(l[i]==0&&r[i]==0)l[i]=1,r[i]=m;
    for(int i=1;i<=m;i++)dp[ind][i]=0;
    int tot=0;
    for(int i=1;i<=n;i++){
        ind^=1;
        memset(dp[ind],0x3f,sizeof(dp[ind]));
        int dw=l[i],up=r[i];
        for(int j=x[i];j<=up;j++)
            dp[ind][j]=min(dp[ind][j],min(dp[ind^1][j-x[i]],dp[ind][j-x[i]])+1);
        if(up==m)for(int j=m-x[i];j<=m;j++)
            dp[ind][m]=min(dp[ind][m],min(dp[ind^1][j],dp[ind][j])+1);
        for(int j=dw;j<=min(up,m-y[i]);j++)
            dp[ind][j]=min(dp[ind][j],dp[ind^1][j+y[i]]);
        for(int j=1;j<dw;j++)dp[ind][j]=INF;
        bool check=0;
        for(int j=1;j<=m;j++)
            if(dp[ind][j]!=INF){check=1;break;}
        if(!check){printf("0\n%d",tot);return 0;}
        if(l[i]>1||r[i]<m)tot++;
    }
    int ans=INF;
    for(int i=1;i<=m;i++)ans=min(ans,dp[ind][i]);
    printf("1\n%d",ans);
    return 0;
}