P1052 강 건너기(상태 압축 dp)
10277 단어 동적 기획
문제풀이
상태 이동 방정식
dp[i] = dp[i-k]+stone[i], s <= k <= t
을 쉽게 얻어낼 수 있다.그중 i
대표는 i
까지 걸어갈 때 돌을 몇 개 밟았는가.30퍼센트의 데이터에 대해 직접 이렇게 하면 된다.그러나 데이터 범위10^9
는 메모리가 전혀 부족하다.자세히 살펴보면 최대 100개의 돌만 있고 매번 뛰는 거리는 최대 10개 단위로 그 안에 돌이 없는 거리가 매우 큰 것이 분명하다.여기에 작은 지식이 필요합니다: lcm(1,2,3,4,5,6,7,8,9,10) = 2520
.즉 0부터 아무리 뛰어도 결국 2520까지 뛴다.그래서 두 돌 사이의 거리가 2520을 넘으면 나머지 것을 얻을 수 있다. 예를 들어 0
에서 2521
까지 뛰면 아무리 뛰어도 2520
까지 뛴다. 그러면 0
에서 1
까지 뛰는 셈이다.이렇게 압축된 경로의 크기는 100*2520을 초과하지 않는다.코드
#include
using namespace std;
const int maxn = 250000+100;
const int INF = 0x3f3f3f;
// dp[i] = dp[i-k]+stone[i]; s <= k <= t
int a[maxn],d[maxn],stone[maxn],dp[maxn];
int main() {
int L,S,T,M;
scanf("%d", &L);
scanf("%d%d%d", &S, &T, &M);
for(int i = 1; i <= M; ++i)
scanf("%d", &a[i]);
sort(a+1,a+1+M);
for(int i = 1; i <= M; ++i)
d[i] = (a[i]-a[i-1])%2520;
for(int i = 1; i <= M; ++i) {
a[i] = a[i-1]+d[i];
stone[a[i-1]+d[i]] = 1;
}
int r = a[M];
memset(dp, INF, sizeof dp);
dp[0] = 0;
int ans = INF;
for(int i = 1; i <= r+T; ++i) {
for(int j = S; j <= T; ++j) {
if(i-j >= 0)
dp[i] = min(dp[i], dp[i-j]+stone[i]);
if(i >= r)
ans = min(ans, dp[i]);
}
}
cout << ans << endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
01 가방, 완전 가방, 다중 가방 dp(동적 기획 입문 dp)01 가방은 2진법으로 직접 표시할 수 있지만 데이터 양이 너무 많으면 시간을 초과하는 것이 폭력이다.01 가방의 사상은 바로 이 물품에 대해 내가 넣은 가치가 큰지 안 넣은 가치가 큰지 비교하여 방정식 f[i][v...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.