一道很好的dp题。
看到数据规模和题目不难想到dp瞎搞。方程也很容易,
f[i][j] 表示在前 i 个里面经历 j 次出逃可以取到最少的修改数
有难度是预处理和转移。想到以每一次逃跑从什么时候开始作为决策,那么就要预处理从 i时刻 到 j时刻 逃跑一次的修改次数
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 1e2 + 10; int N, a[MAXN]; int f[MAXN][MAXN], cnt[MAXN][MAXN]; int main() { cin>>N; for(int i = 1; i <= N; i++) scanf(" %d", &a[i]); for(int i = 1; i <= N; i++){ int tmp = 0; for(int j = i; j <= N; j++) { if(a[j] != j - i) ++tmp; cnt[i][j] = tmp; } } memset(f, 0x3f, sizeof(f)); f[0][0] = 0; for(int i = 1; i <= N; i++) for(int j = 1; j <= i; j++) for(int k = 0; k < i; k++) f[i][j] = min(f[i][j], f[k][j - 1] + cnt[k + 1][i]); for(int i = 1; i <= N; i++) printf("%d ", f[N][i]); return 0; }