UVA11125-Arrange Some Marbles (dp)
UVA11125-Arrange Some Marbles (dp)
Question Link
I will give you n Marbles of different colors, and then give the number of marbles of each color. Now you are required to sort these marbles, and you must have at most three marbles of the same color. The marbles of the same color are called a group. The length and color of each adjacent group are different, and the first two groups must also meet the requirements.
Solution: n <3000 was scared before the problem was solved. There are still so many states of dp in the back, and the complexity is too high. After reading the problem solution, we will find that all the situations will be included in the dp, so as long as the complexity of the dp array is enough, it has nothing to do with n. Because this question contains the number of marbles, You need to record the remaining number of marbles of each color. Then it is 8? 8? 8? 8. (an octal number can be used instead of four parameters.) because the adjacent colors and lengths are required to be different, three more parameters are required? 4. It stores the color length of the last time. The trouble is what to do at the beginning and end. If you name the first group, the corresponding end will be well processed. So start 3 more? 4. Store the first color and size. So the complexity is 8? 8? 8? 8? 144. Note: When the value is 0, the output is 1.
Why does it have nothing to do with n, because the question changes only the number of colors and the number of colors, and we will see four colors in dp, all the numbers that will appear are included.
Code:
#include
#include
#include using namespace std;const int maxn = 4500;const int maxs = 5;const int maxc = 5;int N, PS, PC;int num[maxc];int f[maxn][maxs][maxc][maxs][maxc];int dp (int state, int s, int c) { int& ans = f[state][PS][PC][s][c]; if (ans != -1) return ans; if (!state) { if (PS != s && PC != c) return ans = 1; return ans = 0; } int tmp[maxc]; int tS = state; for (int i = N - 1; i >= 0; i--) { if (tS >= (1<<(3*i))) { tmp[i] = tS/(1<<(3*i)); tS %= (1<<(3*i)); } else tmp[i] = 0; } ans = 0; for (int i = 0; i < N; i++) { if (i == c) continue; for (int j = 1; j <= min(3, tmp[i]); j++) { if (j == s) continue; ans += dp(state - (j * (1<<(3*i))), j, i); } } return ans;}void solve () { scanf ("%d", &N); for (int i = 0; i < N; i++) scanf ("%d", &num[i]); int state = 0; for (int i = 0; i < N; i++) state += num[i] * (1<<(3*i)); int ans = 0; if (state) { for (int c = 0; c < N; c++) for (int s = 1; s <= min(num[c], 3); s++) { PS = s; PC = c; ans += dp(state - s * (1<<(3*c)), s, c); } } else ans = 1; printf ("%d\n", ans);}int main () { int T; scanf ("%d", &T); memset (f, -1, sizeof(f)); while (T--) { solve(); } return 0;}