动态规划的好题
状态转移很简单,dp[i] = dp[i-k] + st[i] ,k是移动距离,st[i]判断i位置是否有石头,但是距离太大,需要压缩路径。
K∈[1,10],lcm[1,10] = 2520,将石子间的距离距离对2520取模。而后进行DP递推即可
#include<stdio.h> #include<algorithm> #include<string.h> #include<stdlib.h> #include<iostream> #include<stack> #include<vector> using namespace std; #define LL long long #define INF 999999999 const int mod = 2520; int st[1000005]; int d[1000005]; int pos[105]; int dp[1000005]; int main() { int L; int S,T,M; cin >> L >> S >> T >> M; for(int i=1;i<=M;i++) cin >> pos[i]; sort(pos+1,pos+1+M); for(int i=1;i<=M;i++) d[i] = (pos[i] - pos[i-1])%2520; for(int i=1;i<=M;i++) { pos[i] = pos[i-1] + d[i]; st[pos[i]] = 1; } int n = pos[M]; for(int i=1;i<=n+T;i++) dp[i] = M; dp[0] = 0; for(int i=1;i<=n+T;i++) { for(int j=S;j<=T;j++) { if(i >= j) dp[i] = min(dp[i],dp[i-j]); dp[i] += st[i]; } } int ans = M; for(int i=n;i<=n+T;i++) ans = min(ans,dp[i]); cout << ans << endl; return 0; }