题意: 给一个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. 动态规划题目——背包

    背包问题 1. 01背包 [HDOJ 2955.Robberies] [HDOJ 1203.I NEED A OFFER!] [HDOJ 1864.最大报销额] 2. 完全背包 [HDOJ 2159. ...

  2. 【 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 ...

  3. dp,sp,px相互转化

    方法一: public int sp2px(float sp) {return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, ...

  4. [JS][dp]题解 | #打家劫舍(一)#

    题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...

  5. HDU 2084 数塔(DP)(JAVA版)

    数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...

  6. dp cf 20190615

    A. Timofey and a tree 这个不算是dp,就是一个思维题,好难想的思维题,看了题解才写出来的, 把点和边分开,如果一条边的两个点颜色不同就是特殊边,特殊边两边连的点就叫特殊点, 如果 ...

  7. BZOJ 1003[ZJOI2006]物流运输(SPFA+DP)

    Problem 1003. -- [ZJOI2006]物流运输 1003: [ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MB Submit ...

  8. [NOI2005]聪聪与可可(期望dp)

    题意:给一张无向图,有一只猫和一只老鼠,猫每秒会向老鼠的方向移动两个单位,若它们的距离为一,那么只会移动一个单位,老鼠会等概率向周围移动一步或不动,求猫抓到老鼠的期望时间. Solution luog ...

  9. Codeforces 903F Clear The Matrix(状态压缩DP)

    题目链接 Clear The Matrix 题意 给定一个$4 * n$的矩形,里面的元素为$'.'$或$'*'$.现在有$4$种正方形可以覆盖掉$'*'$,正方形的边长分别为$1,2,3,4$. 求 ...

  10. 喵哈哈村的魔法考试 Round #1 (Div.2) 题解源码(A.水+暴力,B.dp+栈)

    A.喵哈哈村的魔法石 发布时间: 2017年2月21日 20:05   最后更新: 2017年2月21日 20:06   时间限制: 1000ms   内存限制: 128M 描述 传说喵哈哈村有三种神 ...

最新文章

  1. 互联网协议 — TLS — 安全四要素
  2. 数据结构与算法:归并排序
  3. oracle和dba,oracle db、dba和rdba
  4. 成功解决ValueError: setting an array element with a sequence.
  5. 浅谈设计模式01-策略模式
  6. PythonNote01_HTML标签
  7. 如何将iso文件安装到VirtualBox里的ubuntu去
  8. 字符串比较中NSNumericSearch选项的工作原理
  9. (54)Verilog HDL下升沿采样
  10. Python语法报错相关语句
  11. Ample Sound Ample Bass Metal Ray5 for mac - 低弦音软件
  12. MaxToBlende安装详细方法
  13. jQuery手动触发事件
  14. 塑形管理小程序开发(二)-原型图绘制
  15. 四大基本反应类型的关系_中学化学中的四种基本反应类型,氧化还原反应和物质的变化!...
  16. 修改layui绿色为蓝色
  17. oracle 输出全角空格,mac系统中如何切换全角半角?苹果电脑输入法全角半角切换快捷键介绍...
  18. sdnu1385.Problem A: XOR(连续异或规律)
  19. PERCENTILE_CONT
  20. python pygame模块按键响应

热门文章

  1. 融资轮数划分 天使轮 种子轮 preA A A+ B轮 C轮
  2. capturing self strongly in this block is likely to lead to a retain cycle 警告解决
  3. 改造摄像头模块成开发板
  4. C语言基础(十三)系统错误信息
  5. 武林传奇之七剑下天山java游戏开发商_武林传奇2之七剑下天山的配方
  6. 【运维】在阿里云服务器上给Ubuntu安装桌面系统
  7. matlab系统频域分析,基于MATLAB的系统频域分析的实现
  8. 苹果cms模板_苹果cms怎么做seo?
  9. Linux云计算好学吗?Linux云计算运维学习资料 Vim编辑器
  10. Feature Enhancement Network: A Refined Scene Text Detector