A small backpack DP's troubles

Topic links: https://nanti.jisuanke.com/t/40854

The meaning of problems: there are n (n <= 1000) number cards, each card is divided into two cells, and each cell may have from 1 to 10 points, all together and to the box as P1, all together under the Giga and for the P2, seeking want | P1-P2 | minimum, need to flip many times

Solution to a problem is given:

Normal practice is to use DP, DP may be a two-dimensional array, where DP performed using one-dimensional array. dp [i] represents a minimum number of operations at the upper and lower phase difference. Significance of difference between the upper and lower because it is possible negative, right shifting the entire array is theoretically the maximum vertical difference of the actual program dp [i + N] is above dp [i] is represented by

Flip down will change each time the difference, this change is recorded as the value of a [j], the value changes should be twice the initial value. State transition equation is dp [ia [j]] = min (dp [ia [j]], dp [i] +1) while taking into account the difference with a negative number, the classification of a difference discuss the initial situation, DP different circumstances in different directions.
Finally dp array to find the minimum value of the output can reach to both sides from the N.

Two-dimensional code is also easy to understand

#include<bits/stdc++.h>
using namespace std;
int dp[1005][20005];
int a[1005];
const static int INF=0x7fffff;
int main()
{
    int n;
    scanf("%d",&n);
    int tx=0,ty=0;
    for(int i=1;i<=n;i++)
    {
        register int x,y;
        scanf("%d %d",&x,&y);
        tx+=x;
        ty+=y;
        a[i]=(y-x)*2;
    }
    int t=tx-ty;
    int N=1000;
    for(int i=0;i<=1000;i++)
    for(int j=0;j<=20000;j++)
    dp[i][j]=INF;
    dp[0][t+N]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=20000;j++)
        {
            if(j-a[i]>=0)
            {
                if(dp[i-1][j-a[i]]!=INF)
                dp[i][j]=min(dp[i-1][j],dp[i-1][j-a[i]]+1);
                else
                dp[i][j]=dp[i-1][j];
            }
        }
    }
    int ans;
    for(int i=0;i<=1000;i++)
    {
        //cout<<dp[n][N-i]<<" "<<dp[n][N+i]<<" ";
        if(dp[n][N-i]!=INF||dp[n][N+i]!=INF)
        {
            ans=min(dp[n][N-i],dp[n][N+i]);
            break;
        }
    }
    cout<<ans;
}

However, when converted into a one-dimensional encounter many problems, spend a lot of time, the first point is one-dimensional time to consider a [i] is positive or negative, but also with different situations

Still have a consistent state transition equation of the second point in that discussion Points

#include <bits / STDC ++ H.>
 the using  namespace STD; 
typedef Long  Long LL;
 const  int INF = . 1 << 30 ;
 const  int MAXN = + 1E3 . 7 ;
 int A [MAXN];
 int DP [ 20010. ]; // vertical difference when the minimum number of operations of I (in this case the number of array I + 10000) 
int main () {
     int n-; Scanf ( " % D " , & n-);
     int X, Y, TX = 0 , TY = 0 ;
     for ( int I =. 1 ; I <= n-; I ++ ) { 
        Scanf ( " % D% D " , & X, & Y); 
        TX + = X, TY + = Y; 
        A [I] = (YX) * 2 ; // every turn card, by one minus one, so that by 2 
    }
     int T = the TX- TY;
     for ( int I = 0 ; I <= 20000 ; I ++) DP [I] = INF; 
    DP [ 1000 + T] = 0 ; // The initial state 
    for ( int I = . 1 ; I <= n-; I ++ ) {
         IF (A [I] <= 0){
            for(int j=0;j<=20000+a[i];j++){
                if(dp[j-a[i]]!=inf)dp[j]=min(dp[j],dp[j-a[i]]+1); 
            }
        }
        else for(int j=20000;j>=a[i];j--){
            if(dp[j-a[i]]!=inf)dp[j]=min(dp[j],dp[j-a[i]]+1);
        }
    }
    int ans;
    for(int i=0;i<=1000;i++){
        //cout<<dp[10000+i]<<" "<<dp[10000-i]<<endl;
        if(dp[1000+i]!=inf||dp[1000-i]!=inf){
            ans=min(dp[1000+i],dp[1000-i]);
            break;
        }
    } 
    cout<<ans<<endl;
    return 0;
 }

 

Guess you like

Origin www.cnblogs.com/qingjiuling/p/11334956.html