【HDU4960】Another OCD Patient
题意
给出一个长度为n的整数序列。可以将一段连续的序列进行合并。合并的长度不同代价不同。问付出最少多少代价可以将这个序列变成一个对称的序列。n<=5000
分析
一看题感觉是个dp很好写啊。f[i][j]为令区间[i,j]对称的最小花费。那么转移并不难想
f[i][j]=min(f[i][j],f[i+l1][j-l2]+val[l1-i+1]+val[j-l2+1] | sum[l1]-sum[i-1]==sum[j]-sum[l2-1]);
然后按照区间dp的写法就写了一个迭代然后T掉了。看了一下这样好像是n^3的?下面是T的代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int MAX = +;
int dp[MAX][MAX],a[MAX],v[MAX];
LL sum[MAX];
int dfs(int L,int R) {
if(L>=R) return ;
if(~dp[L][R]) return dp[L][R];
LL sum1,sum2; int ans=a[R-L+];
for(int i=L,j=R;i<j;) {
sum1=sum[i]-sum[L-];
sum2=sum[R]-sum[j-];
if(sum1==sum2) {
ans=min(ans,dfs(i+,j-)+a[i-L+]+a[R-j+]);
i++; j--;
}
else if(sum1>sum2) j--;
else i++;
}
return dp[L][R]=ans;
}
int main() {
int n;
while(scanf("%d",&n)==&&n) {
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++) {
scanf("%d",&v[i]);
sum[i]=sum[i-]+v[i];
}
for(int i=;i<=n;i++) {
scanf("%d",&a[i]);
}
memset(dp,-,sizeof(dp));
int ans=dfs(,n);
printf("%d\n",ans);
}
然后我去网上查了一下,发现这个思想用记忆搜索可以过。。。emmm想一下,貌似是啊,记忆搜索是n^2logn?下面是记忆搜索的代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> using namespace std;
const int maxn=+;
const int INF=;
int a[maxn],val[maxn],f[maxn][maxn];
int n;
long long sum[maxn];
int dfs(int L,int R){
if(f[L][R]!=-)
return f[L][R];
f[L][R]=val[R-L+];
for(int i=L,j=R;i<j;){
long long sum1=sum[i]-sum[L-];
long long sum2=sum[R]-sum[j-];
if(sum1==sum2){
f[L][R]=min(f[L][R],dfs(i+,j-)+val[i-L+]+val[R-j+]);
i++,j--;
}
else if(sum1>sum2)j--;
else i++;
}
return f[L][R];
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
sum[]=;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
}
for(int i=;i<=n;i++)
scanf("%d",&val[i]);
memset(f,-,sizeof(f));
int ans=dfs(,n);
printf("%d\n",ans);
}
return ;
}
然后又开始想迭代该怎么写···
先按照上面的方法预处理出一个pos[maxn]数组,j=pos[i],sum[i]=sum[n]-sum[j-1]。也就是说1-i的和等于pos[i]到n的和。
设一个dp数组f[i]为将1-i和将pos[i]到n合并的最小花费是多少。
转移:f[i]=min(f[i],f[j]+val[i-j]+val[pos[j]-pos[i]])
最终答案是 ans=min(f[i]+val[pos[i]-i-1]);
恩,就是这样。下面是AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream> using namespace std;
const int INF=;
const int maxn=+;
int a[maxn],val[maxn],f[maxn],pos[maxn];
long long sum[maxn]; int n;
int main(){
while(scanf("%d",&n)!=EOF&&n){
sum[]=;
memset(pos,,sizeof(pos));
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
}
for(int i=;i<=n;i++)
scanf("%d",&val[i]);
int i=,j=n;
while(i<j){
long long sum1=sum[i];
long long sum2=sum[n]-sum[j-];
if(sum1==sum2){
pos[i]=j;
i++,j--;
}
else if(sum1<sum2)i++;
else j--;
}
memset(f,,sizeof(f));
/*for(int i=1;i<=n;i++){
printf("%d ",pos[i]);
}*/
f[]=val[n];
for(int i=;i<=n;i++){
if(!pos[i])continue;
f[i]=val[i]+val[n-pos[i]+];
for(int j=;j<i;j++){
if(pos[j]!=){
f[i]=min(f[i],f[j]+val[i-j]+val[pos[j]-pos[i]]);
}
}
}
int ans=val[n]; for(int i=;i<=n;i++)
if(pos[i]||i==){
if(pos[i]>i+)
ans=min(ans,f[i]+val[pos[i]-i-]);
else
ans=min(ans,f[i]);
}
printf("%d\n",ans); /* for(int i=0;i<=n;i++)
printf("%d %d %d\n",i,pos[i],f[i]);*/
}
return ;
}
【HDU4960】Another OCD Patient的更多相关文章
- 【转载】如何破解受保护的excel密码
[工具] 1.电脑一台(安装有Microsoft Excel) 2.受保护excel一个 [步骤] 1.首先,打开受保护的Excel表格,按"ALT"+"F11" ...
- 【Java】-NO.20.Exam.1.Java.1.001- 【1z0-807】- OCEA
1.0.0 Summary Tittle:[Java]-NO.20.Exam.1.Java.1.001-[1z0-807] Style:EBook Series:Java Since:2017-10- ...
- Python高手之路【六】python基础之字符串格式化
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新
[原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- Python高手之路【三】python基础之函数
基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...
- Python高手之路【一】初识python
Python简介 1:Python的创始人 Python (英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种解释型.面向对象.动态数据类型的高级程序设计语言,由荷兰人Guido ...
随机推荐
- OpenCV-Python cv2.imdecode()和cv2.imencode() 图片解码和编码
cv2.imdecode()函数从指定的内存缓存中读取数据,并把数据转换(解码)成图像格式;主要用于从网络传输数据中恢复出图像. cv2.imencode()函数是将图片格式转换(编码)成流数据,赋值 ...
- Ant入门之引用外部jar文件
笔者在java项目开发中经常遇到引用外部Jar包的情况,使用ant打包过程中需要对其引用.现在此简单记忆以飨来者. 此处引用Log4j,具体程序HelloLog4j.java: package oat ...
- Java [Leetcode 347]Top K Frequent Elements
题目描述: Given a non-empty array of integers, return the k most frequent elements. For example,Given [1 ...
- 1138. Postorder Traversal (25)
Suppose that all the keys in a binary tree are distinct positive integers. Given the preorder and in ...
- 接口测试基础——第一篇smtplib发送文字邮件
现在我们就开始进入接口测试框架的知识准备阶段,今天是第一篇,很简单的,就是发送纯文字的电子邮件,会的童鞋可以忽略,不会的就多敲几遍,直到自己能敲出来为止~~ # coding: utf-8 impor ...
- 读论文系列:Object Detection ICCV2015 Fast RCNN
Fast RCNN是对RCNN的性能优化版本,在VGG16上,Fast R-CNN训练速度是RCNN的9倍, 测试速度是RCNN213倍:训练速度是SPP-net的3倍,测试速度是SPP-net的3倍 ...
- js删除局部变量的实现方法
lert('value:'+str+'\ttype:'+typeof(str)) //声明变量前,引用 var str="dd"; alert('value:'+str+'\tty ...
- Linux环境安装git
git配置 源码安装 检测当前git版本是否是2.7.4以上 git --version 如果没有安装git直接源码安装即可,如果安装了先删除原来的git. yum -y remove git 先安装 ...
- SQL Server数据库优化经验总结
优化数据库的注意事项: 1.关键字段建立索引. 2.使用存储过程,它使SQL变得更加灵活和高效. 3.备份数据库和清除垃圾数据. 4.SQL语句语法的优化.(可以用Sybase的SQL Expert, ...
- Eclipse里git提交冲突rejected – non-fast-forward
Eclipse里commit代码,其实只是提交到本地仓库,需要push才会提交到远程的git仓库,这时是一个本地仓库到远程仓库的同步过程.Git是分布式的,每个人在本地仓库维护本地的自己的那一份代码, ...