能量(energy)

Description

​ 有一块能量田,它的形状是 n*m的矩形,每一个格子上都有一个能量值 a[x][y] (可正可负)。一块矩形田的能量定义为它的每个格子的能量值之和。

​ 现在,亮亮需要选择一块正方形的能量田,用它的能量来为自己的魔法棒充 值。他当然希望所选择的能量田所含的能量最大,请你帮助他求出这个最大值。

​ 数据保证能量田中至少有一个格子的能量值非负。

Input

一行两个整数 n 和 m。

接下来 n 行,每行 m 个整数。

Output

输出只有一个整数,表示最大的能量。

数据范围,\(1\leq n,m \leq 200\)

明显\(n^3\)可做.

二维前缀和切了!用时6min

不过貌似很多人都挂了?

PS:初值不要赋成0,对起始的每个格子的值取\(max\)

然后枚举正方形边长.

根据二维前缀和的容斥即可.

代码

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. #define int long long
  5. #define R register
  6. using namespace std;
  7. inline void in(int &x)
  8. {
  9. int f=1;x=0;char s=getchar();
  10. while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
  11. while(isdigit(s)){x=x*10+s-'0';s=getchar();}
  12. x*=f;
  13. }
  14. int n,m,res[208][208],ans;
  15. signed main()
  16. {
  17. freopen("energy.in","r",stdin);
  18. freopen("energy.out","w",stdout);
  19. in(n),in(m);
  20. for(R int i=1;i<=n;i++)
  21. for(R int j=1,x;j<=m;j++)
  22. {
  23. in(x);
  24. res[i][j]=res[i-1][j]+res[i][j-1]-res[i-1][j-1]+x;
  25. ans=max(ans,x);
  26. }
  27. R int lim=min(n,m);
  28. for(R int len=2;len<=lim;len++)
  29. for(R int i=1;i<=n-len+1;i++)
  30. for(R int j=1;j<=m-len+1;j++)
  31. {
  32. R int tmp=res[i+len-1][j+len-1];
  33. tmp-=res[i+len-1][j-1];
  34. tmp-=res[i-1][j+len-1];
  35. tmp+=res[i-1][j-1];
  36. ans=max(ans,tmp);
  37. }
  38. printf("%lld\n",ans);
  39. fclose(stdin);
  40. fclose(stdout);
  41. return 0;
  42. }

摘桃(peach)

Description

​ 小林家的桃园里一共有 n 棵桃树,且第 i 棵桃树结有 A[i]个桃子。到了桃子 成熟的季节,如果不及时摘下来,就会从树上掉下来,一旦掉到了地上,桃子就 会因碰撞致坏而无法出售。

​ 小林知道这个消息后,连忙带上了工具,准备去采摘桃子。小林每一天都可 以选择任意一棵桃树,将其上的桃子全部采摘下来。而每一天结束时,第 i 株桃 树会落下 d[i]个桃子(落到一个不剩为止),这些落下的桃子就会因摔坏而被浪 费掉。(注意,对于每一天,小林先采摘桃子,然后一天结束,接下来桃树落桃 子。) 小林一共有 k 天的时间,在这 k 天内,他最多能采摘多少个桃子呢?

Input

第一行有两个整数 n 和 k。

第二行 n 个整数 A[i]表示每株桃树一开始结的桃子数量。

第三行 n 个整数 d[i]表示每株桃树在每天结束时会落下的桃子数量。

Output

一个整数,即小林能采摘的最多的桃子数量 。

这题做过,切!

做法:贪心+DP

很显然,我们优先考虑摘每天掉落的多的桃子.

(防止后面没办法接)

所以贪心地对其掉落的数量进行排序.

设\(DP\)状态

\(f[i][j]\)代表第\(j\)天处理到第\(i\)棵树的最多桃子数量.

考虑状态转移.

  1. 摘桃子
  2. 不摘桃子

\[f[i][j]=max(f[i-1][j],f[i-1][j-1]+now)
\]

这个\(now\)就是当前剩下的.

还有需要注意的是,如果掉没了,我们就不摘,要等于\(0\)。

代码

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. #define R register
  5. using namespace std;
  6. const int gz=1008;
  7. inline void in(int &x)
  8. {
  9. int f=1;x=0;char s=getchar();
  10. while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
  11. while(isdigit(s)){x=x*10+s-'0';s=getchar();}
  12. x*=f;
  13. }
  14. int n,k,f[gz][gz],ans;
  15. struct cod{int a,d;}tree[gz];
  16. inline bool ccp(const cod&a,const cod&b)
  17. {
  18. return a.d>b.d;
  19. }
  20. int main()
  21. {
  22. freopen("peach.in","r",stdin);
  23. freopen("peach.out","w",stdout);
  24. in(n),in(k);
  25. for(R int i=1;i<=n;i++)in(tree[i].a);
  26. for(R int i=1;i<=n;i++)in(tree[i].d);
  27. sort(tree+1,tree+n+1,ccp);
  28. for(R int j=1;j<=k;j++)
  29. for(R int i=1;i<=n;i++)
  30. {
  31. R int now=tree[i].a-(j-1)*tree[i].d;
  32. if(now<0)now=0;
  33. f[i][j]=max(f[i-1][j],f[i-1][j-1]+now);
  34. }
  35. for(R int i=1;i<=k;i++)ans=max(f[n][i],ans);
  36. printf("%d\n",ans);
  37. fclose(stdin);
  38. fclose(stdout);
  39. return 0;
  40. }

魔法通道(road)

Description

​ 亮亮在一条魔法线上按 1,2,3...n 的顺序依次建立了 n 个魔法点,每个魔法点 有两个属性, Si 表示位置, Ii 表示魔力值。对于两个点 i 和 j(i < j),若满足 |Si-Sj|<=(Ii+Ij),则亮亮可以花费(j-i)^2 的魔法值建立一条从 i 到 j 的魔法通道。

​ 现在,有一个小精灵正处于 1 号魔法点,她想要通过魔法通道到达 n 号点, 亮亮希望能用最少的魔法值来帮助她。请你帮亮亮计算一下,他最少需要消耗多少魔法值。

Input

第一行有一个整数 n,表示一共有 n 个魔法点。

接下来 n 行,每行有两个整数 Si 和 Ii,含义如上所述。

Output

一个整数,表示最少消耗的魔法值。

若小精灵无论如何也到达不了 n 号魔法点,则输出-1。

这题对我来说不可做啊.

我们的做法可以\(get\)到\(70pts\)

前部分60分,可以暴力\(DP\) \(O(n^2)\)

然后最后10分,可以特判\(-1\).

\(f[i]\)代表到处理到\(i\)的最小魔法值.

转移方程为

\[f[i]=min(f[i],f[j]+(j-i)^2) \ \ \ \ \ \ \ j\in[1,i)
\]

这应该不是很难理解,就不多解释了.

这里有一个小优化.倒叙枚举\(j\),再判断

\[if((i-j)^2>=f[i])\ break
\]

可以多得30pts。

因为我们的\((j-i)^2\)如果比\(f[i]\)都要大,再加上\(f[j]\)就没有必要去更新\(f[i]\)了.

这样为什么是可行的?

因为我们从左向右处理,\(f[j]\)已经被处理过,如果能够更新,就已经更新了我们的答案.

而\(f[i]\)是极大值的话(未被更新),不会被\((i-j)^2\)影响,所以\(f[i]\)是一定会被某个位置更新的。

这样可以get到很多分.

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<iostream>
  5. #define int long long
  6. #define R register
  7. using namespace std;
  8. const int gz=300008;
  9. inline void in(R int &x)
  10. {
  11. R int f=1;x=0;char s=getchar();
  12. while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
  13. while(isdigit(s)){x=x*10+s-'0';s=getchar();}
  14. x*=f;
  15. }
  16. int n,f[gz];
  17. struct cod{int s,l;}magic[gz];
  18. inline bool ok(R int i,R int j)
  19. {
  20. return (abs(magic[i].s-magic[j].s))<=(magic[i].l+magic[j].l);
  21. }
  22. inline void init()
  23. {
  24. for(R int i=1;i<=n;i++)in(magic[i].s),in(magic[i].l);
  25. }
  26. signed main()
  27. {
  28. freopen("road.in","r",stdin);
  29. freopen("road.out","w",stdout);
  30. in(n);
  31. init();
  32. for(R int i=2;i<=n;i++)f[i]=21474836476666LL;
  33. f[1]=f[0]=0;
  34. if(n<=233333)
  35. {
  36. for(R int i=1;i<=n;i++)
  37. for(R int j=i-1;j>=1;j--)
  38. {
  39. if(ok(i,j))
  40. f[i]=min(f[i],f[j]+(j-i)*(j-i));
  41. if((j-i)*(j-i)>=f[i])break;
  42. }
  43. printf("%lld",f[n]>=21474836476666LL ? -1:f[n]);
  44. }
  45. else
  46. {
  47. for(R int i=1;i<=n;i++)
  48. for(R int j=i-1;j>=1;j--)
  49. if(ok(i,j))
  50. {
  51. f[i]=min(f[i],f[j]+(j-i)*(j-i));
  52. break;
  53. }
  54. printf("%lld",f[n]>=21474836476666LL ? -1:f[n]);
  55. }
  56. fclose(stdin);
  57. fclose(stdout);
  58. return 0;
  59. }

T3\(\color{red}{官方题解}\)

考察算法: 区间交、 set、 动规

|Si-Sj|≤Ii+Ij 等价于[Si-Ii,Si+Ii]与[Sj-Ij,Sj+Ij]有交。

在 Si,Ii ∈ Z 的 前 提 下 : [Si-Ii,Si+Ii] 与 [Sj-Ij,Sj+Ij] 有 交 等 价 于(Si-Ii,Si+Ii+1)与 (Sj-Ij,Sj+Ij+1)有交。 将每个整点 x 表示成(x,x+1)。

我们按照编号顺序处理各个区间, 最初, set中有三个 Range:

(-∞,S1-I1) Id=0

P1 Id=1

(S1+I1+1,+∞) Id=0

且 dp[1]=0, dp[0]=+∞。

每次, 首先检查 Pi 的两端点, 是否是 set中各 Range 的分界点, 若否, 该端 点 a 必定属于某区间(u,v),Id=x。 从 a 将该区间分裂成(u,a),Id=x 和(a,v),Id=x。

接下来 Pi 恰等于 set中连续的一段 Range 之和(如果只考虑非整点的话) , 枚举这些 Range, 这些 Range 就是可以“无遮拦” 地看到的 Range, 暴力地从这些 Range 对应的 Id 进行转移, 计算得出 dp[i]。

接下来, Pi 的加入将会遮住这些 Range, 在 i 更大时这些 Range 就不可能被“无遮拦” 地看到了。 从 set中 erase 去这些 Range, 用 Pi 代替。

重复这个过程直至 i=N。 输出 dp[N]。

我们发现一旦一个 Range 被用来转移, 它马上会被 erase。 从而, 一个 Range 最多只 会对应一次转移。 所以, 转移的次数≤进入 set 的 Range 数。

进入 set 有两种情况, 也就是循环开始时的分裂区间(每轮 2 次, 每次净增加 1 个区 间) , 和循环末尾的插入 Pi(每轮 1 次, 每次净增加 1 个区间) 。 从而进入 set 的 Range 数是 O(N)级别的, 约等于 3N。

又易证 set 中每一时刻的元素数都≤2N+1, 从而每次转移的复杂度为 O(logN)。 总复杂度为 O(NlogN), 且实现简便, 常数较小。

NOIP2018提高组模拟题(四)的更多相关文章

  1. NOIP2018提高组模拟题(五)

    字符串(string) Description 小林与亮亮正在做一个游戏.小林随意地写出一个字符串,字符串只由大写 字母组成,然后指定一个非负整数 m,亮亮可以进行至多 m 次操作,每次操作 为交换相 ...

  2. 2019.6.21 NOIP2018提高组模拟题(二)

    1.咒语 (curse.pas/c/cpp) [题目描述] 亮亮梦到自己来到了魔法城堡,但一扇巨大的石门阻拦了他通向城堡内的路.正当他沮丧之际,突然发现门上有一处机关,机关上有一张很长的纸条.亮亮拿起 ...

  3. NOIP2018提高组模拟题(六)

    购物(shop) Description 小林来到商店中进行购物.商店里一共有 n 件物品,第 i 件物品的价格为 a[i] 元.小林总共需要购买 m 件物品,他希望他所花费的钱最少,请你计算出最小 ...

  4. 10.18 NOIP2018提高组模拟题(二)

    大水题 1.咒语 (curse.pas/c/cpp) [题目描述] 亮亮梦到自己来到了魔法城堡,但一扇巨大的石门阻拦了他通向城堡内的路.正当他沮丧之际,突然发现门上有一处机关,机关上有一张很长的纸条. ...

  5. NOIP2018提高组模拟题(二)

    咒语(curse) Description 亮亮梦到自己来到了魔法城堡,但一扇巨大的石门阻拦了他通向城堡内的路. 正当他沮丧之际,突然发现门上有一处机关,机关上有一张很长的纸条. 亮亮拿起纸条的一端, ...

  6. jzoj5879. 【NOIP2018提高组模拟9.22】电路图 B

    tj:一道好題 看區間操作可以想到線段樹 並聯操作公式:a1∗a2/(a1+a2)a1*a2/(a1+a2)a1∗a2/(a1+a2) 串聯操作公式:a1+a2a1+a2a1+a2 我們發現,一個區間 ...

  7. 11.5NOIP2018提高组模拟题

    书信(letter) Description 有 n 个小朋友, 编号为 1 到 n, 他们每人写了一封信, 放到了一个信箱里, 接下来每个人从中抽取一封书信. 显然, 这样一共有 n!种拿到书信的情 ...

  8. [JZOJ 5852] [NOIP2018提高组模拟9.6] 相交 解题报告 (倍增+LCA)

    题目链接: http://172.16.0.132/senior/#main/show/5852 题目: 题目大意: 多组询问,每次询问树上两条链是否相交 题解: 两条链相交并且仅当某一条链的两个端点 ...

  9. [JZOJ 5875] [NOIP2018提高组模拟9.20] 听我说,海蜗牛 解题报告(BFS+二分)

    题目链接: http://172.16.0.132/senior/#main/show/5875 题目: 题解: 注意这题只能经过开放的港口 我们考虑用vector存下每个点不能到的点,并把并让vec ...

随机推荐

  1. [Leetcode] scramble string 乱串

    Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...

  2. NodeJS + PhantomJS 前端自动化资源监控

    前言:最近做前端资源监控,看了很多例子,没有达到想要的效果.首先的槽点是PhantomJS的官方文档,真鸡肋,其次是网上的例子,多数是介绍PhantomJS的用法,而并没有介绍怎么完整的去实现,跟官方 ...

  3. 洛谷P1282 多米诺骨牌 (DP)

    洛谷P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中 ...

  4. POJ2699:The Maximum Number of Strong Kings(枚举+贪心+最大流)

    The Maximum Number of Strong Kings Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2488 ...

  5. URAL1277 Cops and Thieves(最小割)

    Cops and Thieves Description: The Galaxy Police (Galaxpol) found out that a notorious gang of thieve ...

  6. 1040: [ZJOI2008]骑士~基环外向树dp

    Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里,在和平环境中 ...

  7. C#网络编程基本字段---IPAddress、IPEndPoint

    命名空间: using System.Net; PAddress类提供了对IP地址的转换.处理等功能.其Parse方法可将IP地址字符串转换为IPAddress实例. 如:IPAddress ip = ...

  8. 【洛谷 P2485】 [SDOI2011]计算器 (BSGS)

    题目链接 第一问:快速幂 第二问:扩欧解线性同余方程 第三问:\(BSGS\) 三个模板 #include <cstdio> #include <cmath> #include ...

  9. R的农场

    R的农场 题目描述 最近,R 终于获得了一片他梦寐以求的农场,但如此大的一片农场,想要做好防卫工作可不是一件容易的事.所以 R 购买了 N 个守卫,分别让他们站在一定的位置上(守卫不可移动,同一位置上 ...

  10. compositionstart 、 compositionend 、 input都存在时的解决办法

    $(function () { var cpLock = true; $('#textbox').off().on({ compositionstart: function () {//中文输入开始 ...