【BZOJ1584】[Usaco2009 Mar]Cleaning Up 打扫卫生【DP】

来源:互联网 发布:矩阵开关说明书 编辑:程序博客网 时间:2024/04/28 00:33

【题目链接】

【hzwer的题解】

维护转移位置的数组有点神。。

/* Telekinetic Forest Guard */#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int maxn = 40005, inf = 0x3f3f3f3f;int n, m, num[maxn], dp[maxn], pos[maxn], pre[maxn], cnt[maxn];inline int iread() {int f = 1, x = 0; char ch = getchar();for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';return f * x;}int main() {n = iread(); m = iread();for(int i = 1; i <= n; i++) num[i] = iread(), dp[i] = inf, pre[i] = -1;n = unique(num + 1, num + 1 + n) - (num + 1);m = sqrt(n);dp[0] = 0;for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++) if(pre[num[i]] <= pos[j]) cnt[j]++;pre[num[i]] = i;for(int j = 1; j <= m; j++) if(cnt[j] > j) {int t = pos[j] + 1;for(; pre[num[t]] > t; t++);pos[j] = t; cnt[j]--;}for(int j = 1; j <= m; j++) dp[i] = min(dp[i], dp[pos[j]] + j * j);}printf("%d\n", dp[n]);return 0;}


0 0
原创粉丝点击