P1006 归零 官方题解
归零
【题目简述】
给定 盏星灯,单独归零第 盏的代价为 ,同时归零相邻的第 盏的代价为 。每盏星灯必须恰好被归零一次,求最小总代价。
【第一档部分分】
这部分 很小,可以考虑直接搜索。
从左到右考虑第一盏还没有归零的星灯 。可以选择单独归零第 盏,也可以在 时同时归零第 盏。递归枚举所有选择即可。
【特殊性质】
若对于任意 ,都有 ,那么同时归零相邻两盏星灯并不会比单独归零它们更优。
于是答案就是
【正解】
考虑最后一次操作。
若第 盏星灯是单独归零的,那么前 盏星灯已经全部归零,代价为 。
若第 盏星灯和第 盏星灯一起归零,那么前 盏星灯已经全部归零,代价为 。
因此,令 表示归零前 盏星灯的最小代价,可以得到
初始时 。从左到右递推即可。
【复杂度】
时间复杂度为 ,空间复杂度为 。若只保留前两项,空间复杂度可以优化到 。
【参考代码】
#include <cstdio>#include <cstring>#include <algorithm>#define MAXN 1000100using namespace std; int n,a[MAXN],b[MAXN];long long dp[MAXN]; int main() { freopen("reset.in","r",stdin); freopen("reset.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n-1;i++) scanf("%d",&b[i]); dp[0]=0;dp[1]=a[1]; for (int i=2;i<=n;i++) { dp[i]=min(dp[i-1]+1ll*a[i],dp[i-2]+1ll*b[i-1]); } printf("%lld\n",dp[n]); return 0;}