[Noip 2009 普及组 T4] [Luogu P1070] 道路游戏

一道很迷的\(dp\)。

感谢大爱无疆的sy

开始的时候采用的二维状态但是并不对)

然后把状态改成一维\(AC\)

\(Solution\):

状态:开始想的是\(f[i][j]\),表示到达\(i\)时间时在\(j\)点处的最多金币数。

转移方程设置为:\(f[i][j]=max\{f[i-1][j-k]+sum-val[j-k]\}\)其中\(sum\)表示从\(j-k\)走到\(j\)所赚的金币数

但这样是不对的,因为题目中:

也就是上一个机器人消失的地方并不一定要买下一个机器人,而是可以换另一个地方买。

如果硬要设计地点的话,应该将\(f[i-1][j-k]\)变为\(max\{f[i-1][1,2,……n]\}\)

这样时间复杂度是\(O(n^4)\)的,想过题可能在想\(peach\)

经过思考,我们发现地点是没什么用的,所以将第二维去掉,\(f[i]\)表示时间为\(i\)时能获得的最大金币数;

转移方程:\(f[i]=max\{f[i-k]+sum-val[d],d=(j-k)\%n+n\}\)

表示在\(d\)点购买的机器人从\(d\)点走到\(j\)点赚取的金币数,枚举\(j、d\),取得\(f[i]\)时的最大值

\(sum\)表示从\(d\)走到\(j\)获得的金币数,最简单的方法,暴力求解:

int pay(int a,int b,int x,int y) {
    int rtn=0,j=a;
    for(int i=x+1;i<=y;i++) {
        rtn+=cost[j][i];
        j++;
        if(j>n) j=1;
    }
    return rtn;
}
//表示从a走到b,时间从x变成y所获得的金币数

\(Code\):

#include<bits/stdc++.h>

using namespace std;

inline int read() {
    int ans=0;
    char last=' ',ch=getchar();
    while(ch>'9'||ch<'0') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

int n,m,p;
int cost[1010][1010];
int val[1010];
int f[1010];

int pay(int a,int b,int x,int y) {
    int rtn=0,j=a;
    for(int i=x+1;i<=y;i++) {
        rtn+=cost[j][i];
        j++;
        if(j>n) j=1;
    }
    return rtn;
}

int main() {
    n=read();
    m=read();
    p=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            cost[i][j]=read();
    for(int i=1;i<=n;++i)
        val[i]=read();
    memset(f,0x9f,sizeof(f));
    f[0]=0;
    for(int i=1;i<=m;++i) { // time i
        for(int j=1;j<=n;++j) { // node j
            for(int k=1;k<=p&&k<=i;++k) { // k
                int d=j-k;
                if(d<=0)
                    d=d%n+n;
                int sum=pay(d,j,i-k,i);
                f[i]=max(f[i],f[i-k]+sum-val[d]);
            }
        }
    }
    printf("%d",f[m]);
    return 0;
}

这样会\(TLE\),求\(pay\)实在是太慢了。

因为\(k\)是从小到大枚举的,也就是从只从\(j\)往后退一步,到往后退\(p\)步,赚取的金币数刚好是可以累加的。

所以定义一个\(sum=0\)每次枚举\(k\)时,\(sum+=cost[j-k][i-k+1]\)

#include<bits/stdc++.h>

using namespace std;

inline int read() {
    int ans=0;
    char last=' ',ch=getchar();
    while(ch>'9'||ch<'0') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

int n,m,p;
int cost[1010][1010];
int val[1010];
int f[1010];

int main() {
    n=read();
    m=read();
    p=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cost[i][j]=read();
    for(int i=1;i<=n;i++)
        val[i]=read();
    memset(f,0x9f,sizeof(f));
    f[0]=0;
    for(int i=1;i<=m;i++) { // time i
        for(int j=1;j<=n;j++) { // node j
            int sum=0;
            for(int k=1;k<=p&&k<=i;k++) { // zoule k
                int d=j-k;
                if(d<=0)
                    d=d%n+n;
                sum+=cost[d][i-k+1];
                f[i]=max(f[i],f[i-k]+sum-val[d]);
            }
        }
    }
    printf("%d",f[m]);
    return 0;
}

原文地址:https://www.cnblogs.com/zhuier-xquan/p/12114538.html

时间: 2024-09-30 14:13:06

[Noip 2009 普及组 T4] [Luogu P1070] 道路游戏的相关文章

Luogu P1070 道路游戏

题面 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编号为1~n,因为马路是环形的,所以第 n 个机器人工厂和第 1 个机器人工厂是由一段马路连接在一起的.小新将连接机器人工厂的这 n 段马路也编号为 1~n,并规定第 i 段马路连接第 i 个机器人工厂和第 i+1 个机器人工厂(1≤i≤n-1),第 n 段马路连接第 n 个机器人工厂和第 1个机器人工厂

洛谷P1070 道路游戏

P1070 道路游戏 题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编号为1~n,因为马路是环形的,所以第 n 个机器人工厂和第 1 个机器人工厂是由一段马路连接在一起的.小新将连接机器人工厂的这 n 段马路也编号为 1~n,并规定第 i 段马路连接第 i 个机器人工厂和第 i+1 个机器人工厂(1≤i≤n-1),第 n 段马路连接第 n 个机器

[Wikioi 2808][NOIP 1998普及组]二的幂次方---HBNU的童鞋过来看看

转载请说明出处:http://blog.csdn.net/cywosp/article/details/27095723 <黑天鹅--如何应对不可预知的未来> 作者:纳西姆?尼古拉斯?塔勒布 关于黑天鹅 在发现澳大利亚黑天鹅之前,所有欧洲人都确信天鹅全部都是白色的,人们在经过上百万次的确定性观察白天鹅之后得到了这一结论,而且一直延续了上千年,直到黑天鹅的出现,从而将这一结论完全打破.通过黑白天鹅的现象说明我们通过观察或经验获得的知识具有严重的局限性和脆弱性,仅仅一次的完全不同的发现就足以颠覆根

CODEVS3294 车站分级 noip普及组T4

题目描述 Description 一条单向的铁路线上,依次有编号为1, 2, …, n的n个火车站.每个火车站都有一个级别,最低为1级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站x,则始发站.终点站之间所有级别大于等于火车站x的都必须停靠.(注意:起始站和终点站自然也算作事先已知需要停靠的站点)例如,下表是5趟车次的运行情况.其中,前4趟车次均满足要求,而第5趟车次由于停靠了3号火车站(2级)却未停靠途经的6号火车站(亦为2级)而不满足要求. 现有m趟车次的运

NOIP2008 普及组T4 立体图 解题报告-S.B.S.(施工未完成)

题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容.最近,他准备给小朋友们讲解立体图,请你帮他画出立体图. 小渊有一块面积为m*n的矩形区域,上面有m*n个边长为1的格子,每个格子上堆了一些同样大小的积木(积木的长宽高都是1),小渊想请你打印出这些格子的立体图.我们定义每个积木为如下格式,并且不会做任何翻转旋转,只会严格以这一种形式摆放: 每个顶点用1个加号’+’表示,长用3个”-”表示,宽用1个”/”,高用两个”|”表示.字符’+’,”-”,”/”,”|”的ASCII

NOIP 普及组 T4 子矩阵(--洛谷P2258)

题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素得到一个2*3的子矩阵如右图所示. 9 3 3 3 9 9 4 8 7 4 1 7 4 6 6 6 8 5 6 9 7 4 5 6 1 的其中一个2*3的子矩阵是 4 7 4 8 6 9 相邻的元素:矩阵中的某个元素与其上下左右四个元素(如果存在的话)是相邻的. 矩阵的分值:矩阵中每一对相邻元素之差

NOIP 2015普及组复赛Day1 T1 == Codevs4510 神奇的幻方

时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description: 幻方是一种很神奇的N∗N矩阵:它由数字 1,2,3, … … ,N∗N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将 1写在第一行的中间.之后,按如下方式从小到大依次填写每个数(K= 2,3, … ,N∗N ): 1.若 (K−1)在第一行但不在最后一列,则将 填在最后一行,(K−1)所在列的右一列: 2.若 (K

SDNU 1167.花生采摘【NOIP 2004 普及组】【贪心】【8月6】

花生采摘 Description 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:"欢迎免费品尝我种的花生!--熊字". 鲁宾逊先生和多多都很开心,因为花生正是他们的最爱.在告示牌背后,路边真的有一块花生田,花生植株整齐地排列成矩形网格(如图1).有经验的多多一眼就能看出,每棵花生植株下的花生有多少.为了训练多多的算术,鲁宾逊先生说:"你先找出花生最多的植株,去采摘它的花生:然后再找出剩下的植株里花生最多的,去采摘

【NOIP】普及组2011 表达式的值

[算法]动态规划+后缀表达式 [题解] 先把算式转为后缀表达式后进行DP 令f[s][0]表示使表达式答案为0的方案数 f[s][1]表示使表达式答案为1的方案数 (加法) f[a+b][1]=f[a][0]*f[b][1]+f[a][1]*f[b][0]+f[a][1]*f[b][1] f[a+b][0]=f[a][0]*f[b][0] (乘法) f[a+b][0]=f[a][0]*f[b][0]+f[a][0]*f[b][1]+f[a][1]*f[b][0]f[a+b][1]=f[a][1]