[dp]HDOJ4960 Another OCD Patient
题意: 给一个n, 第二行给n堆的价值v[i], 第三行给a[i]. a[i]表示把i堆合在一起需要的花费.
求把n堆变成类似回文的 需要的最小花费.
思路:
①记忆化搜索 比较好理解...
dp[l][r] 记录l到r的最小花费
枚举对称轴 维护每次l到r之间对称
dp[l][r]=min(dp[l][r], a[cur-l]+a[r-i]+dfs(cur+1, i-1));
l左边和r右边的合并
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <climits> 5 #include <cctype> 6 #include <cmath> 7 #include <string> 8 #include <sstream> 9 #include <iostream> 10 #include <algorithm> 11 #include <iomanip> 12 using namespace std; 13 #include <queue> 14 #include <stack> 15 #include <vector> 16 #include <deque> 17 #include <set> 18 #include <map> 19 typedef long long LL; 20 typedef long double LD; 21 #define pi acos(-1.0) 22 #define lson l, m, rt<<1 23 #define rson m+1, r, rt<<1|1 24 typedef pair<int, int> PI; 25 typedef pair<int, PI> PP; 26 #ifdef _WIN32 27 #define LLD "%I64d" 28 #else 29 #define LLD "%lld" 30 #endif 31 //#pragma comment(linker, "/STACK:1024000000,1024000000") 32 //LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;} 33 //inline int read(){char ch=' ';int ans=0;while(ch<'0' || ch>'9')ch=getchar();while(ch<='9' && ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans;} 34 inline void print(LL x){printf(LLD, x);puts("");} 35 //inline void read(double &x){char c = getchar();while(c < '0') c = getchar();x = c - '0'; c = getchar();while(c >= '0'){x = x * 10 + (c - '0'); c = getchar();}} 36 37 int a[5005]; 38 LL num[5005]; 39 int cost[5005]; 40 int dp[5005][5005]; 41 int dfs(int l, int r) 42 { 43 if(dp[l][r]!=-1) 44 return dp[l][r]; 45 if(l>=r) 46 return dp[l][r]=0; 47 dp[l][r]=cost[r-l]; 48 int cur=l; 49 for(int i=r;i>=l;i--) 50 { 51 for(;cur<i && (num[cur]-num[l-1]<num[r]-num[i-1]);cur++); 52 if(cur==i) 53 break; 54 if(num[cur]-num[l-1]==num[r]-num[i-1]) 55 dp[l][r]=min(dp[l][r], cost[cur-l]+cost[r-i]+dfs(cur+1, i-1)); 56 } 57 return dp[l][r]; 58 } 59 int main() 60 { 61 #ifndef ONLINE_JUDGE 62 freopen("in.txt", "r", stdin); 63 freopen("out.txt", "w", stdout); 64 #endif 65 int n; 66 while(~scanf("%d", &n) && n) 67 { 68 num[0]=0; 69 for(int i=1;i<=n;i++) 70 { 71 scanf("%d", &a[i]); 72 num[i]=num[i-1]+(LL)a[i]; 73 } 74 for(int i=0;i<n;i++) 75 scanf("%d", &cost[i]); 76 for(int i=0;i<=n;i++) 77 fill(dp[i]+i+1, dp[i]+n+1, -1); 78 //memset(dp, -1, sizeof(dp)); 79 printf("%d\n", dfs(1, n)); 80 } 81 return 0; 82 }
HDOJ 4960 记忆化搜索
② 区间dp
结构体里有 SUM和NUM记录 左或右 NUM堆合起来 合成总值为SUM的
左边从1开始往右 右边从n开始往左
Lsum==Rsum了就分别把Lsum合起来 Rsum合起来 分别存进L和R 然后继续往中间
Ltmp和Rtmp分别记录左边和右边分别合到哪里了
L R 搞完以后 按顺序把 L 中间 R 放进final (注意中间)
因为对称 所以只要 dp final 的一半就够了
dp[i]=min(dp[i], dp[j]+cost[左个数]+cost[右个数]);
最后要注意合了 i堆之后 把剩下的全合起来的情况
ans=min(ans, dp[i]+cost[剩下堆数]);
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <climits> 5 #include <cctype> 6 #include <cmath> 7 #include <string> 8 #include <sstream> 9 #include <iostream> 10 #include <algorithm> 11 #include <iomanip> 12 using namespace std; 13 #include <queue> 14 #include <stack> 15 #include <vector> 16 #include <deque> 17 #include <set> 18 #include <map> 19 typedef long long LL; 20 typedef long double LD; 21 #define pi acos(-1.0) 22 #define lson l, m, rt<<1 23 #define rson m+1, r, rt<<1|1 24 typedef pair<int, int> PI; 25 typedef pair<int, PI> PP; 26 #ifdef _WIN32 27 #define LLD "%I64d" 28 #else 29 #define LLD "%lld" 30 #endif 31 //#pragma comment(linker, "/STACK:1024000000,1024000000") 32 //LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;} 33 //inline int read(){char ch=' ';int ans=0;while(ch<'0' || ch>'9')ch=getchar();while(ch<='9' && ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans;} 34 inline void print(LL x){printf(LLD, x);puts("");} 35 //inline void read(double &x){char c = getchar();while(c < '0') c = getchar();x = c - '0'; c = getchar();while(c >= '0'){x = x * 10 + (c - '0'); c = getchar();}} 36 37 struct node 38 { 39 LL SUM; 40 int NUM; 41 }L[5005], R[5005], final[5005]; 42 LL dp[5005]; 43 int a[5005]; 44 int cost[5005]; 45 int Ltop, Rtop, top; 46 int main() 47 { 48 #ifndef ONLINE_JUDGE 49 freopen("in.txt", "r", stdin); 50 freopen("out.txt", "w", stdout); 51 #endif 52 int n; 53 while(~scanf("%d", &n) && n) 54 { 55 memset(L, 0, sizeof(L)); 56 memset(R, 0, sizeof(R)); 57 memset(final, 0, sizeof(final)); 58 memset(a, 0, sizeof(a)); 59 memset(cost, 0, sizeof(cost)); 60 for(int i=1;i<=n;i++) 61 scanf("%d", &a[i]); 62 for(int i=1;i<=n;i++) 63 scanf("%d", &cost[i]); 64 65 LL Lsum=a[1], Rsum=a[n]; 66 int Lnum=1, Rnum=1; 67 Ltop=Rtop=0; 68 int Ltmp=1, Rtmp=n; 69 for(int i=1, j=n; i<j;) 70 { 71 while(Lsum!=Rsum) 72 { 73 if(i==j) 74 break; 75 if(Lsum<Rsum) 76 { 77 Lnum++; 78 Lsum+=a[++i]; 79 } 80 else if(Rsum<Lsum) 81 { 82 Rnum++; 83 Rsum+=a[--j]; 84 } 85 } 86 if(Lsum==Rsum) 87 { 88 L[Ltop].SUM=Lsum, L[Ltop++].NUM=Lnum; 89 R[Rtop].SUM=Rsum, R[Rtop++].NUM=Rnum; 90 Lsum=a[++i]; 91 Rsum=a[--j]; 92 Lnum=Rnum=1; 93 Ltmp=i; 94 Rtmp=j; 95 } 96 } 97 top=0; 98 for(int i=0;i<Ltop;i++) 99 final[++top]=L[i]; 100 if(Ltmp<=Rtmp) 101 { 102 int sum=0; 103 for(int i=Ltmp;i<=Rtmp;i++) 104 sum+=a[i]; 105 final[++top].SUM=sum, final[top].NUM=Rtmp-Ltmp+1; 106 } 107 for(int i=Rtop-1;i>=0;i--) 108 final[++top]=R[i]; 109 for(int i=1;i<=top/2;i++) 110 { 111 int tmp1=final[i].NUM, tmp2=final[top-i+1].NUM; 112 dp[i]=LLONG_MAX; 113 for(int j=i-1;j>=0;j--) 114 { 115 dp[i]=min(dp[i], dp[j]+cost[tmp1]+cost[tmp2]); 116 tmp1+=final[j].NUM; 117 tmp2+=final[top-j+1].NUM; 118 } 119 } 120 LL minn=LLONG_MAX; 121 LL ans=n; 122 for(int i=0;i<=top/2;i++) 123 { 124 minn=min(minn, dp[i]+cost[ans]); 125 ans-=final[i+1].NUM+final[top-i].NUM; 126 } 127 print(minn); 128 } 129 return 0; 130 }
HDOJ 4960 区间dp
转载于:https://www.cnblogs.com/Empress/p/4063818.html
[dp]HDOJ4960 Another OCD Patient相关推荐
- 动态规划题目——背包
背包问题 1. 01背包 [HDOJ 2955.Robberies] [HDOJ 1203.I NEED A OFFER!] [HDOJ 1864.最大报销额] 2. 完全背包 [HDOJ 2159. ...
- 【 HDU - 5459】Jesus Is Here(dp)
题干: I've sent Fang Fang around 201314 text messages in almost 5 years. Why can't she make sense of w ...
- dp,sp,px相互转化
方法一: public int sp2px(float sp) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, ...
- [JS][dp]题解 | #打家劫舍(一)#
题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...
- HDU 2084 数塔(DP)(JAVA版)
数塔 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...
- dp cf 20190615
A. Timofey and a tree 这个不算是dp,就是一个思维题,好难想的思维题,看了题解才写出来的, 把点和边分开,如果一条边的两个点颜色不同就是特殊边,特殊边两边连的点就叫特殊点, 如果 ...
- BZOJ 1003[ZJOI2006]物流运输(SPFA+DP)
Problem 1003. -- [ZJOI2006]物流运输 1003: [ZJOI2006]物流运输 Time Limit: 10 Sec Memory Limit: 162 MB Submit ...
- [NOI2005]聪聪与可可(期望dp)
题意:给一张无向图,有一只猫和一只老鼠,猫每秒会向老鼠的方向移动两个单位,若它们的距离为一,那么只会移动一个单位,老鼠会等概率向周围移动一步或不动,求猫抓到老鼠的期望时间. Solution luog ...
- Codeforces 903F Clear The Matrix(状态压缩DP)
题目链接 Clear The Matrix 题意 给定一个$4 * n$的矩形,里面的元素为$'.'$或$'*'$.现在有$4$种正方形可以覆盖掉$'*'$,正方形的边长分别为$1,2,3,4$. 求 ...
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解源码(A.水+暴力,B.dp+栈)
A.喵哈哈村的魔法石 发布时间: 2017年2月21日 20:05 最后更新: 2017年2月21日 20:06 时间限制: 1000ms 内存限制: 128M 描述 传说喵哈哈村有三种神 ...
最新文章
- 互联网协议 — TLS — 安全四要素
- 数据结构与算法:归并排序
- oracle和dba,oracle db、dba和rdba
- 成功解决ValueError: setting an array element with a sequence.
- 浅谈设计模式01-策略模式
- PythonNote01_HTML标签
- 如何将iso文件安装到VirtualBox里的ubuntu去
- 字符串比较中NSNumericSearch选项的工作原理
- (54)Verilog HDL下升沿采样
- Python语法报错相关语句
- Ample Sound Ample Bass Metal Ray5 for mac - 低弦音软件
- MaxToBlende安装详细方法
- jQuery手动触发事件
- 塑形管理小程序开发(二)-原型图绘制
- 四大基本反应类型的关系_中学化学中的四种基本反应类型,氧化还原反应和物质的变化!...
- 修改layui绿色为蓝色
- oracle 输出全角空格,mac系统中如何切换全角半角?苹果电脑输入法全角半角切换快捷键介绍...
- sdnu1385.Problem A: XOR(连续异或规律)
- PERCENTILE_CONT
- python pygame模块按键响应
热门文章
- 融资轮数划分 天使轮 种子轮 preA A A+ B轮 C轮
- capturing self strongly in this block is likely to lead to a retain cycle 警告解决
- 改造摄像头模块成开发板
- C语言基础(十三)系统错误信息
- 武林传奇之七剑下天山java游戏开发商_武林传奇2之七剑下天山的配方
- 【运维】在阿里云服务器上给Ubuntu安装桌面系统
- matlab系统频域分析,基于MATLAB的系统频域分析的实现
- 苹果cms模板_苹果cms怎么做seo?
- Linux云计算好学吗?Linux云计算运维学习资料 Vim编辑器
- Feature Enhancement Network: A Refined Scene Text Detector