LichKing 希望收集邪恶的黑暗力量,并依靠它称霸世界。
世间的黑暗力量被描述成一个长度为N 的非负整数序列{Ai},每次它可以选择这个序列中的两个相邻的正整数,让他们的值同时减一并获得一点邪恶力量,直到不存在满足条件的数。
然而你不希望他能够得逞,所以你会使得他收集的能量尽可能少。
1<=n<=1e5,1<= ∑ni=1ai <=5e6
考场去撸第三题了,这题没有仔细想,其实这题是比第三题水的。
第一种方法:
1<= ∑ni=1ai <=5e6这个提醒太明显了。
所以可以随手设出 fi,j,0/1 表示第i个剩下j,第i-1个是否为0。
fi,j,0=min(fi−1,a[i]−j,0,fi−1,a[i]−j,1)+a[i]−j(a[i]−j<=a[i−1])
fi,j,1=min(fi−1,k,0)+a[i]−j(a[i−1]>=k>=a[i]−j)
Ans=min(fn,k,0(a[n]>=k>=0),fn,0,1)
第二种方法:
可以注意到最后的序列每两个数一定为0,即连续四个数会出现两个0。
所以设 fi 为a[i]=0且1-i合法最小代价.
fi=min()
1.fi−1+a[i]
2.fi−2+a[i]
3.fi−3+max(a[i−1],a[i])
…
i-4以下的转移要确定把4个数弄合法的最小代价,由于连续四个数以上会出现至少2个0,我只用由第二个0转移过来,而不用从第一个0转移过来,因为第一个0会转移到第二个0去,由第一个0转移过来的情况已经在前3种转移中出现过了,所以i-4以下的转移是不必要的。
最后 Ans=min(fn,fn−1) 。
于是得到了一个虐爆Tj的O(n)做法。
这个做法的关键在于最终形成序列的性质,算是比较好的思路了。
Code(1):
#include
#define fo(i, x, y) for(int i = x; i <= y; i ++)
#define fd(i, x, y) for(int i = x; i >= y; i --)
#define min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int N = 1e5 + 5, M = 5e6 + 5;
int n, a[N], o, f[2][M][2];
int main() {
freopen("dark.in", "r", stdin);
freopen("dark.out", "w", stdout);
scanf("%d", &n);
fo(i, 1, n) scanf("%d", &a[i]);
fo(i, 1, n) {
o = !o;
fo(j, 0, a[i]) {
if(a[i] - j <= a[i - 1])
f[o][j][0] = min(f[!o][a[i] - j][0], f[!o][a[i] - j][1]) + a[i] - j; else
f[o][j][0] = 1e9;
}
int mi = 1e9;
fo(j, a[i] + 1, a[i - 1]) mi = min(mi, f[!o][j][0]);
fo(j, 0, a[i]) {
if(a[i] - j <= a[i - 1]) mi = min(mi, f[!o][a[i] - j][0]);
f[o][j][1] = mi + a[i] - j;
}
}
int ans = f[o][0][1];
fo(i, 0, a[n]) ans = min(ans, f[o][i][0]);
printf("%d", ans);
}
Code(2):
#include
#define fo(i, x, y) for(int i = x; i <= y; i ++)
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
using namespace std;
int n, a[100005], f[100005];
int main() {
freopen("dark.in", "r", stdin);
freopen("dark.out", "w", stdout);
scanf("%d", &n);
fo(i, 1, n) scanf("%d", &a[i]);
f[0] = 0;
fo(i, 1, n) {
f[i] = f[i - 1] + a[i];
if(i >= 2) f[i] = min(f[i], f[i - 2] + a[i]);
if(i >= 3) f[i] = min(f[i], f[i - 3] + max(a[i], a[i - 1]));
}
printf("%d", min(f[n], f[n - 1]));
}