ABC 251 | E - Takahashi and Animals

题意描述

Takahashi有N头牛,编号为1N,他可以通过以下N种方式来喂养牛:

  • 花费A1喂养牛1和牛2
  • 花废A2喂养牛2和牛3
  • 花费A3喂养牛3和牛4
  • ... ...
  • 花费AN1喂养牛N1和牛N
  • 花费AN喂养牛N和牛1

Takahashi的目标是使得每一头牛都被喂养,并使得花费最小,输出该最小花费。

数据范围

  • 2N3×105
  • 1Ai109

题目解析

动态规划问题常用来解决最优化问题,而动态规划应用于这类问题的优势在于解决了重叠子问题,避免重复计算。动态规划算法的关键在于状态表示和状态转移。
首先对问题进行分析

  • 若想牛1被喂养,操作1和操作N需至少选择一个
  • 若想牛2被喂养,操作1和操作2需至少选择一个
  • 若想牛3被喂养,操作2和操作3需至少选择一个
  • ... ...
  • 若想牛N1被喂养,操作N2和操作N1需至少选择一个
  • 若想牛N被喂养,操作1和操作N需至少选择一个

状态表示
f[i][0]表示已对前i1个进行决策且第i个不选的最小费用.
f[i][1]表示已对前i1个进行决策且第i个选的最小费用.

状态转移
f[i][0]=f[i1][1]
f[i][1]=min(f[i1][0],f[i1][1])+a[i]

边界条件及问题答案

  • 若不进行操作1
    f[1][0]=0,f[1][1]=inf
    此时必须进行操作N,故答案为f[N][1]
  • 若进行操作1
    f[1][1]=a[1],f[1][0]=inf
    此时答案为min(f[n][0],f[n][1])

将以上两种情况的答案取最小值作为该问题的答案。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 3e5 + 10;

ll f[N][2];
ll a[N];
int n;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%lld", &a[i]);

    ll ans = 1e18;

    //不选1
    f[1][0] = 0, f[1][1]= 1e18;
    for(int i = 2; i <= n; i ++){
        f[i][0] = f[i - 1][1];
        f[i][1] = min(f[i - 1][1], f[i - 1][0]) + a[i];
    }
    ans = min(ans, f[n][1]);

    //选1
    f[1][0] = 1e18, f[1][1]= a[1];
    for(int i = 2; i <= n; i ++){
        f[i][0] = f[i - 1][1];
        f[i][1] = min(f[i - 1][1], f[i - 1][0]) + a[i];
    }
    ans = min(ans, f[n][1]);
    ans = min(ans, f[n][0]);

    printf("%lld\n", ans);

    return 0;
}

posted @   小菜珠的成长之路  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示