Rock Valley P1282 Dominoes (Linear DP)

Title: title link

 

analyze: 

I thought of this idea at first, but it seems that I need to open a large array, so I feel that it should not work.

Then I gave up thinking of other methods, but I never expected to notice that it can be optimized by rolling (in fact, it can be passed without optimization)

Define dp[i][j] to represent the minimum number of turns to make up the j score up to the ith number

The transfer equation is as follows

If you choose to rotate i this domino dp[i][j-Sub[i]] = min( dp[i][j-Sub[i]], dp[i-1][j] )

If you choose not to rotate dp[i][j+Sub[i]] = min( dp[i][j+Sub[i]], dp[i-1][j] + 1 )

But there is a problem, that is, it is necessary to consider the case where the second dimension fraction has negative numbers

Just add an offset, turn negative to positive

 

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
const int INF = 0x3f3f3f3f;
int dp[2][(6*maxn)<<1];
int L[maxn], R[maxn], Sub[maxn];

int main(void)
{
    int N, Tot = 0 ;
    scanf("%d", &N);
    for(int i=1; i<=N; i++)
        scanf("%d %d", &L[i], &R[i]),
        Sub[i] = L[i] - R[i],
        Tot + = abs (Sub [i]);

    memset(dp, INF, sizeof(dp));
    dp[0][Tot] = 0;
    int idx = 1;

    for(int i=1; i<=N; i++){
        for(int j=0; j<=(Tot<<1); j++){

            if(j+Sub[i] >= 0 && j+Sub[i] <= (Tot<<1) )
                dp[idx][j+Sub[i]] = min(dp[idx][j+Sub[i]], dp[idx^1][j]);

            if(j-Sub[i] >= 0 && j-Sub[i] <= (Tot<<1) )
                dp[idx][j-Sub[i]] = min(dp[idx][j-Sub[i]], dp[idx^1][j]+1);

        }
        if (i != N){ /// In the case of rolling optimization, the initial of each layer is INF, so the next layer should be assigned as INF 
            idx ^= 1 ;
             for ( int j= 0 ; j<=( Tot<< 1 ); j++ )
                dp[idx][j] = INF;
        }
    }

    int ans = INF;
     for ( int l=Tot,r=Tot; l>= 0 && r<=(Tot<< 1 ); l--,r++){ /// After adding the offset, 0 is defined by Tot Instead, swipe left and right from 0 until the first flip count is not the initial value is the answer 
        if (dp[idx][l] != INF && dp[idx][r] != INF) ans = min( dp[idx][l], dp[idx][r]);
         else  if (dp[idx][l] != INF) ans = dp[idx][l];
         else  if (dp[idx][r ] != INF) ans = dp[idx][r];
         if (ans != INF) break ;
    }

    printf("%d\n", ans);
    return 0;
}
View Code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324694167&siteId=291194637