首页 > 其他分享 >洛谷题单指南-动态规划3-P1070 [NOIP2009 普及组] 道路游戏

洛谷题单指南-动态规划3-P1070 [NOIP2009 普及组] 道路游戏

时间:2024-05-14 19:31:53浏览次数:17  
标签:洛谷题 机器人 NOIP2009 工厂 金币 购买 时刻 dp P1070

原题链接:https://www.luogu.com.cn/problem/P1070

题意解读:1~n个环形机器人工厂,相邻工厂之间的道路是1~n,每个时刻可以从任意工厂购买机器人,走不超过p时间,不同工厂购买机器人花费不同的金币,不同时刻走到不同道路也能得到不同的金币,问一共m时间,最多可以得到多少金币(需减去购买机器人的花费)。

解题思路:

1、状态表示

有n个机器人工厂、n条马路、m个时间,每次机器人最多走p时间,

设a[i][j]表示走第i号马路,第j时刻产生的金币数,

设b[i]表示从第i号机器人工厂购买机器人所消耗的金币数,

设dp[i]表示前i时间能得到的最多金币数。

2、样例模拟

2 3 2 
1 2 3 
2 3 4 
1 2

一共有2个机器人工厂,总共走3步,每次购买机器人最多走2步

道路在不同时刻产生的金币数:

  时刻:1 时刻:2 时刻:3
道路:1 1 2 3
道路:2 2 3 4

每个机器人工厂购买机器人的花费:

工厂号 购买机器人金币数
工厂:1 1
工厂:2 2

第1时刻:

  从工厂1购买机器人:

    走1步:dp[1] = -1 + 1 = 0,说明:-从工厂1购买机器人+第1时刻走道路1

    走2步:dp[2] = -1 + 1 + 3 = 3,说明:-从工厂1购买机器人+第1时刻走道路1+第2时刻走道路2

  从工厂2购买机器人:

    走1步:dp[1] = -2 + 2 = 0,说明:-从工厂2购买机器人+第1时刻走道路2

    走2步:dp[2] = -2 + 2 + 2 = 2,说明:-从工厂2购买机器人+第1时刻走道路2+第2时刻走道路1

此时,dp[1]的最大值为0,dp[2]的最大值为3,所以dp[1] = 0,dp[2] = 3

第2时刻:

  从工厂1购买机器人:

    走1步:dp[2] = f[1] - 1 + 1 = 0,说明:前1个时间获得的最大金币数-从工厂1购买机器人+第2时刻走道路1

    走2步:dp[3] = f[1] - 1 + 1 + 4,说明:前1个时间获得的最大金币数-从工厂1购买机器人+第2时刻走道路1+第3时刻走道路2

  从工厂2购买机器人:

    走1步:dp[2] = f[1] - 2 + 3 = 1, 说明:前1个时间获得的最大金币数-从工厂2购买机器人+第2时刻走道路2

    走2步:dp[3] = f[1] - 2 + 3 + 3 = 4,说明:前1个时间获得的最大金币数-从工厂2购买机器人+第2时刻走道路2+第3时刻走道路1

此时,dp[2]的最大值为3,所以dp[2] = 3

第3时刻:(一共m=3,到第3时刻就只能走1步了)

  从工厂1购买机器人:

    走1步:dp[3] = dp[2] - 1 + 3 = 5,说明:前2个时间获得的最大金币数-从工厂1购买机器人+第3时刻走道路1

  从工厂2购买机器人:

    走1步:dp[3] = dp[2] - 2 + 4 = 5,说明:前2个时间获得的最大金币数-从工厂2购买机器人+第3时刻走道路2

此时,dp[3]的最大值为5,所以最终答案就是dp[3] = 5。

3、状态转移

根据以上分析,可以通过三重循环来枚举实现递推

for i:1 ~ m的时刻

  for j:1 ~ n的工厂

    sum = dp[i-1] - 从工厂j购买机器人的花费

    for k:1 ~ p的步数(注意:走k步后时间不能超过m)

      走到的工厂位置 = j + k - 1

      if(走到的工厂位置 % n)  //处理环形

        走到的工厂位置 %= 走到的工厂位置

      当前时刻 = i + k - 1

      sum += a[走到的工厂位置][当前时刻]

      dp[当前时刻] = max(dp[当前时刻],sum)

4、初始值

初始化为极大值

for(int i = 1; i <= n; i++) dp[i] = -0x3f3f3f3f;

5、结果

根据定义为dp[m]

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 1005, M = 1005;

int n, m, p;
int a[N][M]; //a[i][j]表示第i号马路,第j时刻的金币数
int b[N]; //b[i]表示第i号机器人工厂购买机器人的金币数
int dp[N]; //dp[i]表示前i时间能得到的最多金币数

int main()
{
    cin >> n >> m >> p;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> a[i][j];
    for(int i = 1; i <= n; i++) 
        cin >> b[i];
    for(int i = 1; i <= n; i++) dp[i] = -0x3f3f3f3f;
    for(int i = 1; i <= m; i++) //枚举时刻
    {
        for(int j = 1; j <= n; j++) //枚举工厂
        {
            int sum = dp[i-1] - b[j]; //sum初始是前i-1时间的最大收益减去在j工厂购买机器人的消耗
            for(int k = 1; k <= p && i + k - 1 <= m; k++)
            {
                int pos = j + k - 1; //走到哪个工厂
                if(pos % n) pos %= n;
                int time = i + k - 1; //当前的时刻
                sum += a[pos][time]; //sum加上走到pos马路time时刻获得的金币
                dp[time] = max(dp[time], sum);
            }
        }
    }
    cout << dp[m];

    return 0;
}

 

标签:洛谷题,机器人,NOIP2009,工厂,金币,购买,时刻,dp,P1070
From: https://www.cnblogs.com/jcwy/p/18191936

相关文章

  • 洛谷题单指南-动态规划3-P1063 [NOIP2006 提高组] 能量项链
    原题链接:https://www.luogu.com.cn/problem/P1063题意解读:本质上是一个环形石子合并问题,计算合并产生的最大能量。解题思路:对于环形DP问题,可以把环拆开,并复制2倍长度,然后用1~n的区间长度去枚举1、状态表示设structnode{inthead,tail}用于表示每一个项链节点,其中有头、尾......
  • 洛谷题单指南-动态规划3-P4170 [CQOI2007] 涂色
    原题链接:https://www.luogu.com.cn/problem/P4170题意解读:长度为n的字符串,每次可以将连续一段填为同一个字符,求要填成目标串的最少填涂次数。解题思路:1、状态表示:设s表示目标字符串,dp[i][j]表示将i~j涂成目标"颜色"的最少次数2、状态转移考虑i~j的两端,当i==j,说明只有一个......
  • 洛谷题单指南-动态规划3-P1140 相似基因
    原题链接:https://www.luogu.com.cn/problem/P1140题意解读:两个只包含A、C、G、T4个字符的序列,根据已经定义好的字符-字符的相似度,计算两个序列最大的相似度,两个序列必须每个字符都配对,如果字符不够,可以插入'-'代替。解题思路:本题要解决几个问题:1、状态表示既然有两个序列,设......
  • 洛谷题单指南-动态规划3-P1880 [NOI1995] 石子合并
    原题链接:https://www.luogu.com.cn/problem/P1880题意解读:计算n堆石子合并的最小、最大得分,只不过这n堆石子是环形的,也就是首、尾也相邻,是区间DP的升级版-环形DP问题。解题思路:如果是常规区间DP的方法:对于n堆石子,考察区间的长度范围是1~n先枚举左端点i,范围是1~n再计算右......
  • 洛谷题单指南-动态规划3-P3205 [HNOI2010] 合唱队
    原题链接:https://www.luogu.com.cn/problem/P3205题意解读:给定理想队形,计算初始队形的方案数。解题思路:对于给定理想队形,最后一个人插入有两种可能:从左边插入、从右边插入从左边插入,则意味着前一个数比当前数大,前一个数有可能在左边也有可能在右边从右边插入,则意味着前一个数......
  • 洛谷题单指南-动态规划3-Zuma
    原题链接:https://www.luogu.com.cn/problem/CF607B题意解读:从一组整数中取连续的回文子串,求最少几次可以取完。解题思路:状态表示:设dp[i][j]表示取i~j之间的回文子串所需的最少次数,a[i]表示第i个数状态转移:如果a[i]==a[j],dp[i][j]=dp[i+1][j-1],因为首尾如果相等,其必然可以......
  • 洛谷题单指南-动态规划3-P1775 石子合并(弱化版)
    原题链接:https://www.luogu.com.cn/problem/P1775题意解读:计算合并石子的最小代价,区间DP。解题思路:状态表示:dp[i][j]表示将第i~j堆石子合并的最小代价,m[i]表示第i堆石子质量,s[i]表示前i堆石子质量前缀和状态转移:考虑最后一次合并,设最后一次合并是将i~k合成的一堆与k+1~j合成......
  • 洛谷题单指南-动态规划2-P3147 [USACO16OPEN] 262144 P
    原题链接:https://www.luogu.com.cn/problem/P3147题意解读:将一组数据两两相邻且相同的合并,合并成一个数值+1的数,求合并后的最大值。解题思路:考虑合并后的最大数i,其最后一次必然是由两个i-1合并而来的设dp[i][j]表示以j为左端点,合并最大值为i时的右端点的下一个位置如图:dp[i......
  • 洛谷题单指南-动态规划2-P4310 绝世好题
    原题链接:https://www.luogu.com.cn/problem/P4310题意解读:求最长的子序列长度,使得每相邻两个元素&操作不为0。解题思路:直观来看,可以通过类似最长上升子序列的算法,进行状态转移,但是复杂度为O(n^2),会超时状态表示:dp[i]表示前i个数能产生满足条件的子序列的最长长度状态转移:dp......
  • 洛谷题单指南-动态规划2-P1833 樱花
    原题链接:https://www.luogu.com.cn/problem/P1833题意解读:在有限的时间内,看n株樱花树,第i株樱花树可以看pi次,看每株樱花树耗费时间ti,看每株樱花树一次美学值ci,求最多能看到多少美学值。解题思路:本题实质是一个混合背包问题(pi>0是多重背包,pi=0是完全背包):背包容量:总时间,可以根据......