415 words
2 minutes
[BOJ] DDR 체력 관리
TimeLimit | MemoryLimit | Condition | TAG |
---|---|---|---|
1s | 1024MB | (1 ≤ N ≤ 1000, 1 ≤ K ≤ 10, 1 ≤ sᵢ ≤ 1000, 1 ≤ hᵢ ≤ 100 | Dynamic Programming |
이것도 간단한 dp 문제로 그냥 dp[i][j]가 있을 때 i번째 게임을 할 때, j번째 체력인 경우로 나눠서 정의하고 상태 전이를 해버리면 쉽게 풀리는데 문제가 원하는 순서와 조건에 잘 맞춰야되기 때문에 이상한 곳에서 틀릴 수 있으니 조심하십셔.
정답 코드
#include <iostream>
#include <queue>
#include <set>
#include <algorithm>
#include <random>
#define mod 1000000007LL
#define MAX 1'000'000LL
using namespace std;
using ll = long long;
ll n;
ll dp[2001][101]; // dp[i][j] 일 때, i번째 game에서 hp가 j일 때의 점수
ll uk;
pair<ll, ll> games[2001];
int main(){
cin >> n >> uk;
ll result = 0;
for(int i = 1; i <= n; i++) cin >> games[i].first; // score
for(int i = 1; i <= n; i++){
cin >> games[i].second; // health
}
for(int i = 0; i <= n; i++){
for(int j = 0; j < 101; j++){
dp[i][j] = -1;
}
}
//
// for(int i = 1; i < n; i++){
// for(int j = i+1; j <= n; j++){
// for(int k = 1; k < 101; k++){
//
// dp[j][min(k+(uk* (j - i)), 100LL)] = max(dp[i][k], dp[j][min(k+(uk* (j - i)), 100LL)]);
// if(!dp[i][k] || k+(uk* (j - i)) - games[j].second < 0) continue;
// ll ch = min(100LL, k+(uk* (j - i)) - games[j].second);
// dp[j][ch] = max(dp[i][k] + games[j].first, dp[j][ch]);
// result= max(dp[j][ch], result);
// }
// }
// }
dp[0][100] = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j <= 100; j++){
if(dp[i][j] == -1) continue;
ll ch = min(j+uk, 100LL);
dp[i+1][ch] = max(dp[i+1][ch], dp[i][j]);
if(ch - games[i+1].second >= 0){
dp[i+1][ch - games[i+1].second] = max(dp[i+1][ch - games[i+1].second], dp[i][j] + games[i+1].first);
result = max(result, dp[i+1][ch - games[i+1].second]);
}
// cout << dp[i+1][ch] << " " << ch << " " << i+1 << "\n";
result = max(result, dp[i+1][min(j+uk, 100LL)]);
}
}
cout << result;
return 0;
}
/*
2 0
1 2
99 1
1 5
1
100
*/
[BOJ] DDR 체력 관리
https://compy07.github.io/Blog/posts/boj/29756/