zoukankan      html  css  js  c++  java
  • Gym 101873I

    题目链接:http://codeforces.com/gym/101873/problem/I

    题意:

    给出 $n(1 le n le 300000)$ 个单位时间,每个单位时间给出一个 $x_i(0 le x_i le 32)$ 代表该单位时间内视野内的敌人数目。

    现在你有一个终极武器,每次使用可以消灭视野内所有敌人,但是需要 $m$ 个单位时间进行充能,且刚开始该武器是没有充能的。

    这意味着,第一次可以使用该武器是在第 $m+1$ 个单位时间内,而往后若在第 $i$ 个单位时间使用则下一次使用最早可以在 $m+i$。

    求出最多可以消灭的敌人数目。

    题解:

    假设 $dp[i]$ 表示前 $i$ 个单位时间内能消灭的最多的敌人数目。

    状态转移方程:$dp[i]=maxleft ( max{dp[j]+x[i] | 1 le j le i-m},max{dp[j] | i-m+1 le j < i} ight )$。

    如果用纯暴力dp的话是会超时的,观察式子,不妨维护 $mx[i] = max{dp[1],dp[2], cdots, dp[i]}$,

    则状态转移方程变为 $dp[i] = max left ( mx[i-m] + x[i], mx[i-1] ight )$。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e5+10;
    int n,m,x[maxn];
    int dp[maxn],mx[maxn];
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++) scanf("%d",&x[i]);
        if(n<=m)
        {
            printf("0
    ");
            return 0;
        }
        for(int i=1;i<=m;i++) mx[i]=dp[i]=0;
        for(int i=m+1;i<=n;i++)
        {
            dp[i]=max(mx[i-m]+x[i],mx[i-1]); //求得dp[i]
            mx[i]=max(dp[i],mx[i-1]); //更新mx[i]
        }
        printf("%d
    ",dp[n]);
    }
  • 相关阅读:
    复习事件委托
    模式学习⑧--观察者模式
    模式学习⑦ --中介者模式
    模式学习(六)--- 策略模式
    模式学习(五)--装饰者模式
    模式学习(四)-迭代器
    模式学习(三)- 工厂模式
    模式学习(二)
    linux rpm包解压
    linux patch中的p0和p1的区别
  • 原文地址:https://www.cnblogs.com/dilthey/p/9895840.html
Copyright © 2011-2022 走看看