题意:给n个白球,选其中一些涂为黑色,且给了涂第i个球的花费为ci,要求每m个连续的球中至少有两个黑球,问最小花费是多少?

容易想到一个方程dp[i][j]=min{dp[k][i]}+c[j]

dp[i][j]表示最后上色的两个球分别是第i和第j个球(i<j)时的最优解。

我们从条件每m个连续的球中至少有两个黑球可以得出k的范围j-m<=k<i

如果我们直接按上面这个方程去做的话时间复杂度是O(n*m*m)。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <queue>
  5. #include <algorithm>
  6. #define ll long long
  7. #define mod 113
  8. #define INF 100000000
  9. using namespace std;
  10. ];
  11. ][];
  12. int main()
  13. {
  14. int n,m;
  15. scanf("%d%d",&n,&m);
  16. ; i<=n; ++i) scanf("%d",&c[i]);
  17. memset(dp,0x7f,sizeof(dp));
  18. ; i<=m; ++i)
  19. ; j<i; ++j)
  20. dp[i%mod][i-j]=c[i]+c[j];
  21. ; i<=n; ++i)
  22. ; j<i; ++j)
  23. {
  24. int minn=INF;
  25. for(int k=i-m; k<j&&i-k<=m; ++k)
  26. minn=min(minn,dp[j%mod][j-k]);
  27. dp[i%mod][i-j]=minn+c[i];
  28. }
  29. int ans=INF;
  30. ; --i)
  31. ; i-j<=m&&j>=n-m+; --j)
  32. ans=min(ans,dp[i%mod][i-j]);
  33.  
  34. printf("%d\n",ans);
  35. ;
  36. }

但如果数据范围再大一点,就不行了。
所以我们需要优化一下转移部分。

对于上面那个方程而言,对于相同i,k的右边界是不变的,左边界随着j的变大的而减小。所以我们可以试着从大到小枚举j,这样k的区间就从小变大了。我们可以利用上一个区间的结果,从而降低转移的时间复杂度。

从另一种角度来阐述:

写一下dp[i][j+1]=min{dp[k][i]}+c[j+1],这里k的范围是j-m+1<=k<i。

我们发现这里k的范围是和dp[i][j]那个方程里面的k的范围是有重合的,准确说是dp[k][i]是有重合的。我们假设g=min{dp[k][i]},(j-m+1<=k<i)。这样求dp[i][j]=min{dp[k][i]}+c[j](j-m<=k<i)时,就变成了dp[i][j]=min{dp[j-m][i],g}+c[j]。这样我们只需要以i为阶段,从大到小枚举j就可以把转移这部分的时间复杂度降维O(1)。

这里的计算只适合j大于m的情况,所以需要预处理m以内的部分:dp[i][j]=c[i]+c[j](1<=i<j<=m)。

最终的答案需要从[n-m+1,n]之间的范围之内枚举。

由于卡内存所以要用滚动数组。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #define ll long long
  7. #define mod 101
  8. using namespace std;
  9. ][];
  10. ];
  11. int main()
  12. {
  13. int n,m;
  14. scanf("%d%d",&n,&m);
  15. ; i<=n; ++i)
  16. scanf("%d",&a[i]);
  17. ; i<=m; ++i)
  18. ; j<=m; ++j)
  19. dp[i][j]=a[i]+a[j];
  20. ; i<=n; ++i)
  21. {
  22. int minn=0x7fffffff;
  23. ,n); j>max(i,m)&&j-i<m; --j)
  24. {
  25. minn=min(minn,dp[(j-m+mod)%mod][i%mod]);
  26. dp[i%mod][j%mod]=minn+a[j];
  27. }
  28. }
  29. int ans=0x7fffffff;
  30. ; --i)
  31. ; i-j<m&&j>=n-m+; --j)
  32. ans=min(ans,dp[j%mod][i%mod]);
  33. printf("%d\n",ans);
  34. ;
  35. }

参考:http://wenku.baidu.com/view/89bd5f1e650e52ea551898fb.html

SGU 183 Painting the balls (优化的动态规划)的更多相关文章

  1. sgu 183. Painting the balls 动态规划 难度:3

    183. Painting the balls time limit per test: 0.25 sec.memory limit per test: 4096 KB input: standard ...

  2. SGU 183. Painting the balls( dp )

    dp..dp(i, j)表示画两个点为i-j, i的最优答案. dp(i, j) = min{ dp(i-j, k) } + cost[i] (1≤k≤M-j) 令f(i, j) = min{dp(i ...

  3. SGU 183.Painting the balls

    时间限制:0.25s 空间限制:4M 题意:  在n(n<=10000)个球中,给若干个球涂色,每个球涂色的代价为Ci,使得任意连续m(m<=100)个球中有至少两个球被涂了色. Solu ...

  4. 【Luogu2900】土地征用(斜率优化,动态规划)

    [Luogu2900]土地征用(斜率优化,动态规划) 题面 Description 农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块 ...

  5. 【BZOJ1096】【ZJOI2007】仓库建设(斜率优化,动态规划)

    [BZOJ1096][ZJOI2007]仓库建设(斜率优化,动态规划) 题面 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原 ...

  6. 【BZOJ3675】序列分割(斜率优化,动态规划)

    [BZOJ3675]序列分割(斜率优化,动态规划) 题面 Description 小H最近迷上了一个分隔序列的游戏.在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列.为了得 ...

  7. 【BZOJ2684】【CEOI2004】锯木厂选址(斜率优化,动态规划)

    [BZOJ2684][CEOI2004]锯木厂选址(斜率优化,动态规划) 题面 万恶的BZOJ因为权限题的原因而做不了... 我要良心的提供题面 Description 从山顶上到山底下沿着一条直线种 ...

  8. 【BZOJ3672】【NOI2014】购票(线段树,斜率优化,动态规划)

    [BZOJ3672][NOI2014]购票(线段树,斜率优化,动态规划) 题解 首先考虑\(dp\)的方程,设\(f[i]\)表示\(i\)的最优值 很明显的转移\(f[i]=min(f[j]+(de ...

  9. 图解Leetcode组合总和系列——回溯(剪枝优化)+动态规划

    Leetcode组合总和系列--回溯(剪枝优化)+动态规划 组合总和 I 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 ...

随机推荐

  1. 设置segue跳转页面

    第二种是利用ViewController与ViewController之间,拖拽添加segue 方法中提到的设置segue的identifier界面 在.h文件中声明 - (IBAction)goto ...

  2. python读取指定内存的内容

    import ctypes as ct t = ct.string_at(0x211000, 20) # (addr, size) print t 最好不要用解释性语言来开发底层,一般用C.

  3. iOS开发UIScrollView的底层实现

    起始 做开发也有一段时间了,经历了第一次完成项目的激动,也经历了天天调用系统的API的枯燥,于是就有了探索底层实现的想法. 关于scrollView的思考 在iOS开发中我们会大量用到scrollVi ...

  4. 修改Window的hosts文件提示“该文件被其他程序占用”解决方案

    1.打开C:\Windows\System32\drivers\etc中的hosts 2.右键——>属性——>安全 3.在修改保存就可以了

  5. spring bean初始化顺序

    转载:http://blog.csdn.net/heyutao007/article/details/50326793 常用的设定方式有以下三种:通过实现 InitializingBean/Dispo ...

  6. cl.exe

    http://blog.csdn.net/happyanger6/article/details/7589016

  7. .NET 向SQL里写入非Text类型

    一般来说,在更新DataTable或是DataSet时,如果不采用SqlParameter,那么当输入的Sql语句出现歧义时,如字符串中含有单引号,程序就会发生错误,并且他人可以轻易地通过拼接Sql语 ...

  8. 如何创建一个客户端回调:js获得服务端的内容?

    答案:表面上看去就是前端的js调用服务的C#方法,本质就是ajax,通过XMLHttpRequest对象和服务端进行交互.回调:就说回过头来调用,按理说js是一种脚本语言,怎么能用来调用服务端的呢?就 ...

  9. 斐波那契博弈(Fibonacci Nim)

    问题: 有一堆个数为n(n>=2)的石子,游戏双方轮流取石子,规则如下: 1)先手不能在第一次把所有的石子取完,至少取1颗: 2)之后每次可以取的石子数至少为1,至多为对手刚取的石子数的2倍. ...

  10. S1:对象与JSON

    JSON全称为JavaScript对象表示法(JavaScript Object Notation). JSON是JavaScript中对象的字面量,是对象的表示方法,通过使用JSON,可以减少中间变 ...