HDU4362Dragon Ball【dp优化】

本文深入解析了龙珠收集问题的动态规划解决方案,通过详细解释输入输出格式、题意分析、错误排查及优化过程,帮助读者理解并解决类似问题。通过实例分析,展示了动态规划在优化决策过程中的应用,最终通过调整状态转移方程,成功解决了时间限制问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Dragon Ball

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2196    Accepted Submission(s): 767


Problem Description
Sean has got a Treasure map which shows when and where the dragon balls will appear. some dragon balls will appear in a line at the same time for each period.Since the time you got one of them,the other dragon ball will disappear so he can only and must get one Dragon ball in each period.Digging out one ball he will lose some energy.Sean will lose |x-y| energy when he move from x to y.Suppose Sean has enough time to get any drogan ball he want in each period.We want to know the minimum energy sean will lose to get all period’s dragon ball.
 

Input
In the first line a number T indicate the number of test cases.Then for each case the first line contain 3 numbers m,n,x(1<=m<=50,1<=n<=1000),indicate m period Dragon ball will appear,n dragon balls for every period, x is the initial location of sean.Then two m*n matrix. For the first matrix,the number in I row and J column indicate the location of J-th Dragon ball in I th period.For the second matrix the number in I row and J column indicate the energy sean will lose for J-th Dragon ball in I-th period.
 

Output
For each case print a number means the minimum energy sean will lose.
 

Sample Input
1 3 2 5 2 3 4 1 1 3 1 1 1 3 4 2
 

Sample Output
8
 

Author
FZU
 

Source

这个题卡死我了啊啊啊啊啊啊啊啊啊

终于找到错了啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

啊啊啊啊啊啊啊啊

大意:有n个periodm个龙珠

每个period会出现一些龙珠

但是你每个period只能收集一个龙珠

告诉你每个龙珠在每个时期出现的位置和digging的cost

问最少花费多少cost

分析:

刚开始读错题意了  题目描述?额出问题了?我以为每个水晶球去过之后就不能去了呢

又是1000状态压缩都没法压

之后看到正确题意之后第一反应出来一个10^7的算法

交了一次TLE

之后我就想怎么优化 

看别人题意的时候看到他说用单调队列优化

我想了大概十分钟才终于想通了

对于一个位置pos

dp[i][j] = min(dp[i - 1][k] + abs(pos - k) + cost[i][j])

将其展开

对于pos之前的额k

dp[i][j] = min(dp[i - 1][k] + pos - k + cost[i][j])

对于之后的k

dp[i][j] = min(dp[i - 1][k] + k - pos+ cost[i][j])

我的思路是把每个period的位置都排一次序

对于dp[i][j]只要正着扫一遍k用一个单调队列

然后在倒着扫一遍

然后就wa啊  

后来才找到wa点

我们每次往单调队列里push的不能跟当前状态有任何关系==

以为他会影响到后续状态==

只要把dp方程改一下

pos之前的k dp[i][j] = min(dp[i - 1][k] - pos[i - 1][k]) + pos[i][j] + cost[i][j]

pos之后的k dp[i][j] = min(dp[i - 1][j] + pos[i - 1][k]) + cost[i][j] - pos[i][j]

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 55;
 9 const int maxm = 1005;
10 const int INF = 1000000000;
11 
12 struct Node {
13     int x, y, pos;
14 }node[maxn][maxm];
15 bool cmp(Node n1, Node n2) {
16     return n1.pos < n2.pos;
17 }
18 int cost[maxn][maxm];
19 int dp[maxn][maxm];
20 priority_queue<int, vector<int>, greater<int> > q1, q2;
21 
22 int main() {
23     int t, n, m, x;
24     scanf("%d",&t);
25     while(t--) {
26         scanf("%d %d %d",&n, &m, &x);
27         for(int i = 1; i <= n; i++) {
28             for(int j = 1; j <= m; j++) {
29                 scanf("%d",&node[i][j].pos);
30                 node[i][j].x = i; node[i][j].y = j;
31             }
32         }
33         for(int i = 1; i <= n; i++) {
34             for(int j = 1; j <= m; j++) {
35                 scanf("%d",&cost[i][j]);
36             }
37         }
38         for(int i = 1; i <= n; i++) {
39             sort(node[i] + 1, node[i] + 1 + m, cmp);
40         }
41         memset(dp, 0x3f, sizeof(dp));
42         for(int j = 1; j <= m; j++) {
43             dp[1][j] = abs(x - node[1][j].pos) + cost[node[1][j].x][node[1][j].y];
44         }
45         for(int i = 2; i <= n; i++) {
46             int k = 1;
47             while(!q1.empty()) q1.pop();
48             while(!q2.empty()) q2.pop();
49             for(int j = 1; j <= m; j++) {
50                 for(k; k <= m; k++) {
51                     if(node[i - 1][k].pos > node[i][j].pos) {
52                         break;
53                     }
54                     q1.push(dp[i - 1][k] - node[i - 1][k].pos);
55                 }
56                 if(!q1.empty()) {
57                     dp[i][j] = min(dp[i][j], q1.top() + node[i][j].pos + cost[node[i][j].x][node[i][j].y]);
58                 }
59             }
60             k = m;
61             for(int j = m; j >= 1; j--) {
62                 for(k; k >= 1; k--) {
63                     if(node[i - 1][k].pos < node[i][j].pos) break;
64                     q2.push(dp[i - 1][k] + node[i - 1][k].pos);
65                 }
66                 if(!q2.empty()) {
67                     dp[i][j] = min(dp[i][j], q2.top() + (- node[i][j].pos + cost[node[i][j].x][node[i][j].y]));
68                 }
69             }
70         }
71         int ans = INF;
72 
73         for(int j = 1; j <= m; j++) {
74             ans = min(ans, dp[n][j]);
75         }
76         printf("%d\n", ans);
77     }
78     return 0;
79 }
View Code

 

内容概要:文章基于4A架构(业务架构、应用架构、数据架构、技术架构),对SAP的成本中心和利润中心进行了详细对比分析。业务架构上,成本中心是成本控制的责任单元,负责成本归集与控制,而利润中心是利润创造的独立实体,负责收入、成本和利润的核算。应用架构方面,两者都依托于SAP的CO模块,但功能有所区分,如成本中心侧重于成本要素归集和预算管理,利润中心则关注内部交易核算和获利能力分析。数据架构中,成本中心与利润中心存在多对一的关系,交易数据通过成本归集、分摊和利润计算流程联动。技术架构依赖SAP S/4HANA的内存计算和ABAP技术,支持实时核算与跨系统集成。总结来看,成本中心和利润中心在4A架构下相互关联,共同为企业提供精细化管理和决策支持。 适合人群:从事企业财务管理、成本控制或利润核算的专业人员,以及对SAP系统有一定了解的企业信息化管理人员。 使用场景及目标:①帮助企业理解成本中心和利润中心在4A架构下的运作机制;②指导企业在实施SAP系统时合理配置成本中心和利润中心,优化业务流程;③提升企业对成本和利润的精细化管理水平,支持业务决策。 其他说明:文章不仅阐述了理论概念,还提供了具体的应用场景和技术实现方式,有助于读者全面理解并应用于实际工作中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值