code1319 玩具装箱
2016-04-28 22:11
260 查看
一个划分dp,不过由于划分个数任意,仅用一维数组就可以
设dp[i]表示前i个装箱(任意个箱子)的费用最小值
dp[i]=min(dp[u]+cost(u+1,i))
但是n<=50000,n方的复杂度显然不能接受
设choice[i]数组存下对于每个i值,枚举所得的使f[i]最大的那个u值
打表,发现choice[]是单调不下降的
则每次对于一个新的i,在枚举u时只需要从choice[i-1]开始即可
代码:
为什么是单调的呢?请见 http://wenku.baidu.com/view/ef259400bed5b9f3f90f1c3a.html
至于更好的O(n)的斜率优化,改天再说吧...sleeping
设dp[i]表示前i个装箱(任意个箱子)的费用最小值
dp[i]=min(dp[u]+cost(u+1,i))
但是n<=50000,n方的复杂度显然不能接受
设choice[i]数组存下对于每个i值,枚举所得的使f[i]最大的那个u值
打表,发现choice[]是单调不下降的
则每次对于一个新的i,在枚举u时只需要从choice[i-1]开始即可
代码:
#include<iostream> #include<cstring> #define Size 50005 using namespace std; int n; int c[Size]; long long sum[Size]; long long L; long long dp[Size]; int choice[Size]; long long cost(int l,int r){ long long x=sum[r]-sum[l-1] + r-l; return (x-L)*(x-L); } int main(){ freopen("1319.in","r",stdin); memset(dp,0x7f,sizeof(dp)); cin>>n>>L; for(int i=1;i<=n;i++){ cin>>c[i]; sum[i]=sum[i-1]+c[i]; } dp[0]=0; choice[0]=0; for(int i=1;i<=n;i++){ for(int u=choice[i-1];u<=i-1;u++){ if(dp[u]+cost(u+1,i)<=dp[i]){ dp[i]=dp[u]+cost(u+1,i); choice[i]=u; } } } cout<<dp ; fclose(stdin); return 0; }
为什么是单调的呢?请见 http://wenku.baidu.com/view/ef259400bed5b9f3f90f1c3a.html
至于更好的O(n)的斜率优化,改天再说吧...sleeping
相关文章推荐
- bzoj 3196: Tyvj 1730 二逼平衡树
- CALayer和position和anchorPoint
- php+nginx 上传文件大小限制要修改的文件
- 二叉搜索树的后序遍历序列
- Math app 2.0
- maven 学习---Maven 插件
- var target = event.target
- Symfony2命令行命令详解
- Swift 协议代理的使用和传值
- 在mac上用Xcode写程序, run的时候总是失败, 显示clang: error: linker command failed with exit code 1
- Android Studio系列教程六--Gradle多渠道打包
- AlwaysOn实现只读路由
- 电商网站架构设计
- LNMP环境搭建
- 一次广告投放的感受
- cocoaPods的使用
- 练习三1012
- java 数字组合代码 按顺序,每组无重复,形成一个无重复的字符串
- Spring java-based configuration 配置transaction manager
- Android Studio系列教程五--Gradle命令详解与导入第三方包