POJ1717 Dominoes DP, backpack Deformation
This question is short, and it is easy to understand the meaning of the question with pictures. Each card is divided into the upper and lower parts. There are several points on it, which indicates that the upper part is divided into several, and the following is the same, then place n cards in parallel and vertical. In this way, the upper part of each card forms the first line, and the lower part forms the second line. The sum of the upper and lower two lines is different from that of the gap, each card can be reversed up and down, so that the gap value can be reduced. Ask you to minimize the number of times you need to flip the gap value
First of all, this question is a bit similar to POJ1837, but it is much more troublesome to set the boundary. Because POJ1837 has been done before, I chose this method as soon as I came up, but, the difference between the B value is 6000 and negative. In order to represent a negative number, the array must be open to 12000, so that n is 1000 again, that is, if the power of 10 is more than 7, it will time out, so I have been trying to optimize it, push the one-dimensional data, and then I thought of a solution. I can set a boundary, then, update the range from the left to the right based on the input of a and B. In this way, you do not need to scan 12000 in an extreme way every time, so you start to think about it,
Because a-B may produce negative numbers, the array is opened to double the maximum value, that is, 6000*2, and the boundary is set to 6000, dp [I] [j] indicates the minimum number of flipped ings with the difference value j at the time of the first I. Status transfer is the transfer method of the backpack.
Dp [I] [j] = min (dp [I] [j], dp [I-1] [j-(ai-bi)] + 1 );
Then the question can be optimized because only the value of the question exists. The specific reason is that this blog is very good: click here
But I keep RE. Later I saw this blogger set the boundary to 20000. Why is it 20000? I RE must be at the bottom boundary of the array, because there is a subtraction that may lead to negative subscripts, I have never understood it, and the result is dragged from the afternoon to the evening. Then I found the error here, that is, if the gap value is x, then the upper face value of a card is a = 2, and the lower face value is B = 1. After the card is flipped, the gap value will be reduced by 2, that is, x-2. If this is done, 6000 won't work, in extreme cases, 12000 is subtracted, and more than 20 submissions are finally submitted.
Then I asked a giant to do it again. He directly used the method I first thought of, that is, the method I thought would time out. As a result, he passed, in addition, the array he handed in for the first time is not big enough. The data for this question should be problematic, and the huge code is also given.
Int nnn; int aa [1000 + 55]; int bb [1000 + 55]; int cc [1000 + 55]; int dp [100000 + 55]; int suma, sumb; int sumcc; int le, ri; void init () {suma = sumb = sumcc = 0; memset (aa, 0, sizeof (aa); memset (bb, 0, sizeof (bb); memset (cc, 0, sizeof (cc); memset (dp, 0x7f, sizeof (dp);} int Abs (int x) {return x <0? -X: x;} bool input () {while (cin> nnn) {for (int I = 1; I <= nnn; I ++) {cin> aa [I]> bb [I]; suma + = aa [I]; sumb + = bb [I]; cc [I] = aa [I]-bb [I]; sumcc + = cc [I];} return false;} return true;} void cal () {int ans = dp [0]; le = ri = 12000; dp [12000] = 0; for (int I = 1; I <= nnn; I ++) {if (cc [I]> 0) for (int j = ri + cc [I] * 2; j> = le + cc [I] * 2; j --) dp [j] = min (dp [j], dp [j-cc [I] * 2] + 1); else if (cc [I] <0) for (int j = le + cc [I] * 2; j <= ri + cc [I] * 2; j ++) dp [j] = min (dp [j], dp [j-cc [I] * 2] + 1); ri = max (ri, ri + cc [I] * 2); le = min (le, le + cc [I] * 2);} for (int I = 0; I <= nnn; I ++) {if (12000 + sumcc-I <0) continue; /*****/if (ans> dp [12000 + sumcc-I] | ans> dp [12000 + sumcc + I]) {ans = min (dp [12000 + sumcc-I], dp [12000 + sumcc + I]); cout <
Giant code:
#include
#include
#include using namespace std;const int N = 1000+5;const int Inf = 1<<30;int dp[N][N<<4], a[N], b[N];int n;inline void Update(int &x, int y) { if(x > y) x = y;}void solve() { int mid = 6000; for(int i = 0;i <= n; i++) { for(int j = 0;j <= mid*2; j++) dp[i][j] = Inf; } dp[0][mid] = 0; for(int i = 1;i <= n; i++) { for(int j = 0;j <= mid*2; j++) if(dp[i-1][j] < Inf) { Update(dp[i][j+a[i]-b[i]], dp[i-1][j]); Update(dp[i][j-a[i]+b[i]], dp[i-1][j]+1); } } for(int i = 0;i <= mid; i++) if(dp[n][i+mid]