摘要:
BZOJ_2442 这个题目可以用f[i]表示递推到第i个点时得到的最优解。不妨设A[]表示前缀和,那么当前有两种决策,要么不选当前这个点,要么一并向前选择若干个点,这样可以得到状态转移方程f[i]=max{f[j]+A[i]-A[j+1](i-K-1<=j<=i-2),f[i-1]}。 如果裸着做的话是O(N^2)的,但是对状态转移方程中f[j]+A[i]-A[j+1]变形之后就会得到f[j]-A[j+1]+A[i],这样如果我们用单调队列维护f[j]-A[j+1]的最大值就可以做到O(1)决策了。#include<stdio.h>#include<string 阅读全文
摘要:
POJ_3666 由于递增和递减是类似的,下面不妨只讨论变成递增序列的情况。 我们可以用f[i][j]表示递推到第i个数时,将第i个数变成<=j且满足序列是非减的所需要的最小的代价。由于j的范围较大,可以先离散化,不妨设最后一共有S个不同的数,那么我们要计算的就是f[N][S]。 可以得到f[i][j]=std::min(f[i-1][j]+abs(...),f[i][j-1]),式子中的...表示省略了一部分内容。如果还想优化空间的话,用滚动数组实现即可。#include<stdio.h>#include<string.h>#include<algorit 阅读全文
摘要:
POJ_3670 由于递增和递减是类似的,下面不妨只讨论变成递增序列的情况。 由于Di只有三个数,所以可以考虑将序列分割成三部分,第一部分全部变成1,第二部分全部变成2,第三部分全部变成3。然后我们枚举3开始的位置,这时一共有若干决策,要么前面的全部是1,要么前面有一段2,然后再前面有一段1或者没有,如果每种决策都考察一遍的话整体复杂度就要O(N^2)了,因此考虑优化一下。记当前的位置为i,1的最后一个位置为j,not1[k]表示k以及k之前不是1的数量,not2[k]表示k以及k之前不是2的数量,not3[k]表示k以及k之后不是3的数量,那么我们把决策表示成not2[i]+(not1[j] 阅读全文
摘要:
POJ_3669 广搜一下即可。#include<stdio.h>#include<string.h>#include<algorithm>#include<queue>#define MAXD 310#define INF 0x3f3f3f3fint N, danger[MAXD][MAXD], dis[MAXD][MAXD];int dx[] = {-1, 1, 0, 0, 0}, dy[] = {0, 0, -1, 1, 0};int inside(int x, int y){ return x >= 0 && y & 阅读全文