문제:http://www.spoj.com/problems/BAT2/
각 방의 가중치가 주어지고 두명의 사람이 이동을 한다.
한 사람은 1에서 부터 다른 한사람은 N에서 부터 이동할 때
겹치지 않는 경로로 가중치가 증가하는 순서대로 이동할 때 밟을 수 있는 방의 수의 최댓값을 출력하는 문제이다.
다이나믹 프로그래밍을 이용하여 dp[pos][x][y]의 정의를 1번부터 pos번 정점까지 확인 했을 때 한 사람은 x번 정점을 마지막으로 한사람은 y번 정점을 마지막으로 밟았다고 생각하면 점화식을 세울 수 있다.
dp[pos][x][y]= max(dp[pos][a[pos]][y]+1, dp[pos][x][a[pos]]+1 , dp[pos][x][y])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <cstdio> #include <algorithm> #include <cstring> using namespace std; int dp[103][103][103]; int t, n, a[103], maxx; int func(int pos, int x, int y) { if (pos == n + 1)return 0; int &ret = dp[pos][x][y]; if (ret != -1)return ret; ret = 0; if (a[x] < a[pos]) ret = max(ret, func(pos + 1, pos, y) + 1); if (a[y] > a[pos]) ret = max(ret, func(pos + 1, x, pos) + 1); return ret = max(ret, func(pos + 1, x, y)); } int main() { scanf("%d", &t); while (t--) { maxx = 0; memset(dp, -1, sizeof(dp)); scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); maxx = max(maxx, a[i]); } a[n + 1] = maxx + 1; printf("%d\n", func(1, 0, n + 1)); } return 0; } | cs |