- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在为以下问题寻找一种有效的算法:
有一个包含值的数组,即(注意索引 0 是故意省略的)
Index 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
Value 17, 12, 5, 22, 3, 12, 6, 13, 7, 0, 2, 15
我需要找到的是这些约束下的索引子集:
例如,如果子集长度为 3,总和为 20,则所有可能的解决方案都是
Indices: [1, 7, 12] Sum of values: 17 + 6 + 15 = 38
Indices: [1, 8, 11] Sum of values: 17 + 13 + 2 = 32
Indices: [1, 9, 10] Sum of values: 17 + 7 + 0 = 24
Indices: [2, 6, 12] Sum of values: 12 + 12 + 15 = 39
Indices: [2, 7, 11] Sum of values: 12 + 6 + 2 = 20
Indices: [2, 8, 10] Sum of values: 12 + 13 + 0 = 25
Indices: [3, 5, 12] Sum of values: 5 + 3 + 15 = 23
Indices: [3, 6, 11] Sum of values: 5 + 12 + 2 = 19
Indices: [3, 7, 10] Sum of values: 5 + 6 + 0 = 11
Indices: [3, 8, 9] Sum of values: 5 + 13 + 7 = 25
Indices: [4, 5, 11] Sum of values: 22 + 3 + 2 = 27
Indices: [4, 6, 10] Sum of values: 22 + 12 + 0 = 34
Indices: [4, 7, 9] Sum of values: 22 + 6 + 7 = 35
Indices: [5, 6, 9] Sum of values: 3 + 12 + 7 = 22
Indices: [5, 7, 8] Sum of values: 3 + 6 + 13 = 22
其中 [2, 6, 12]
是最优解,因为它的值和最大。
目前我使用稍微修改过的分区算法遍历所有可能的组合,该算法随着索引总和的增长呈指数增长,所以我想知道是否有更好的方法?
最佳答案
解O(I.S.K)
让我们先做一些命名:
I
是最大的索引(在您的示例中为 12)S
是选择索引的值的总和(在您的示例中为 20)K
是选择的索引个数V[]
链接到索引的值数组maxsum(s, i, k)
使用k
索引可达到的最大总和,所有不同,其值小于或等于i
,其总和为s
。然后你想求maxsum(S, I, K)
您的问题展示了一些良好的特性:
例如,当尝试计算 maxsum(s, i, k)
时,我可以不使用索引 i
,在这种情况下,值为 maxsum (s, i-1, k)
。或者我可以使用索引 i
。在这种情况下,我想解决子问题:索引小于或等于 i-1
且其和为 s-i
的最大和是多少 s-i
使用 k-1
这样的索引。这是值:V[i] + maxsum(s-i, i-1, k-1)
。
因为我们想要达到最大总和,我们最终得到:(编辑:将 maxsum(s-i, i-1, k)
更正为 maxsum(s-i, i-1, k -1)
)
maxsum(s, i, k) = max{ maxsum(s, i-1, k) ; V[i] + maxsum(s-i, i-1, k-1) }
这是 dynamic programming 可以解决的典型问题.
这是一个 C++ 程序示例,它解决了 O(I.S.K)
(空间和时间)中的问题。
我们可以以更大的时间复杂度为代价将空间复杂度提高到 O(I.S)
:O(I.S.K²)
。
如何使用程序
g++ -std=c++14 -g -Wall -O0 dp.cpp -o dp
./dp input.txt
其中 input.txt 是具有以下格式的文件:
示例运行
---- K=1 ----
17 12 5 22 3 12 6 13 7 0 2 15
[ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11][12]
[ 1] 17 17 17 17 17 17 17 17 17 17 17 17
[ 2] 12 12 12 12 12 12 12 12 12 12 12
[ 3] 5 5 5 5 5 5 5 5 5 5
[ 4] 22 22 22 22 22 22 22 22 22
[ 5] 3 3 3 3 3 3 3 3
[ 6] 12 12 12 12 12 12 12
[ 7] 6 6 6 6 6 6
[ 8] 13 13 13 13 13
[ 9] 7 7 7 7
[10] 0 0 0
[11] 2 2
[12] 15
[13]
[14]
[15]
[16]
[17]
[18]
[19]
[20]
---- K=2 ----
17 12 5 22 3 12 6 13 7 0 2 15
[ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11][12]
[ 1]
[ 2] 12 12 12 12 12 12 12 12 12 12 12
[ 3] 29 29 29 29 29 29 29 29 29 29 29
[ 4] 22 22 22 22 22 22 22 22 22 22
[ 5] 17 39 39 39 39 39 39 39 39 39
[ 6] 34 34 34 34 34 34 34 34 34
[ 7] 27 27 29 29 29 29 29 29 29
[ 8] 8 24 24 24 24 24 24 24
[ 9] 25 25 25 30 30 30 30 30
[10] 34 34 34 34 34 34 34
[11] 15 28 28 28 28 28 28
[12] 9 35 35 35 35 35
[13] 18 18 29 29 29 32
[14] 25 25 25 25 27
[15] 19 19 19 24 24
[16] 13 13 13 37
[17] 20 20 20 20
[18] 13 13 27
[19] 7 15 21
[20] 9 28
---- K=3 ----
17 12 5 22 3 12 6 13 7 0 2 15
[ 1][ 2][ 3][ 4][ 5][ 6][ 7][ 8][ 9][10][11][12]
[ 1]
[ 2]
[ 3]
[ 4]
[ 5] 17 17 17 17 17 17 17 17 17 17
[ 6] 34 34 34 34 34 34 34 34 34 34
[ 7] 51 51 51 51 51 51 51 51 51
[ 8] 44 44 44 44 44 44 44 44 44
[ 9] 39 39 41 41 41 41 41 41 41
[10] 42 42 42 42 42 42 42 42
[11] 37 51 51 51 51 51 51 51
[12] 30 46 46 46 46 46 46 46
[13] 39 40 52 52 52 52 52
[14] 20 35 47 47 47 47 47
[15] 37 37 42 42 42 42 44
[16] 31 37 37 37 41 41
[17] 40 40 40 40 40 54
[18] 21 47 47 47 47 49
[19] 41 41 41 41 44
[20] 22 35 35 35 39
index: 12 sum: 20
index: 6 sum: 8
index: 2 sum: 2
max sum: 39
源代码
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <limits>
#include <valarray>
#include <vector>
using namespace std;
auto const INF = numeric_limits<double>::infinity();
struct matrix {
matrix(size_t rows, size_t cols, double value)
: cells(value, rows*cols)
, rows(rows)
, cols(cols)
, value(value)
{}
double& operator() (int r, int c)
{
if(r < 0 || c < 0)
return value;
return cells[r*cols+c];
}
valarray<double> cells;
size_t rows;
size_t cols;
double value;
};
int main(int argc, char* argv[]) {
if(argc > 1)
freopen(argv[1], "r", stdin);
// I: max index
// S: sum of indices
// K: number of indices in the sum S
int I, S, K;
cin >> I >> S >> K;
// load values
vector<double> V(I+1, 0);
for(int i=1; i<=I; ++i)
cin >> V[i];
// dynamic programming:
// --------------------
// maxsum(i, s, k) is the maximal sum reachable using 'k' indices, less
// than or equal to 'i', all differents, and having a sum of 's'
//
// maxsum(i, s, k) =
// -oo if i > s
//
// -oo if i < s && k == 1
//
// V[s] if i >= s && s <= I && k == 1
// -oo if (i < s || s > I) && k == 1
//
// max { V[i] + maxsum(i-1, S-i, k-1), maxsum(i-1, S, k) }
vector<matrix> maxsum(K+1, matrix(S+1, I+1, -INF));
// initialize K=1
for(int s=0; s<=I && s<=S; ++s) {
for(int i=s; i<=I; ++i) {
maxsum[1](s, i) = V[s];
}
}
// K > 1
for(int k=2; k<=K; ++k) {
for(int s=2; s<=S; ++s) {
for(int i=1; i<=I; ++i) {
auto l = V[i] + maxsum[k-1](s-i, i-1);
auto r = maxsum[k](s, i-1);
maxsum[k](s, i) = max(l, r);
}
}
}
// display the whole dynamic programming tables (optional)
for(int k=1; k<=K; ++k) {
cout << "---- K=" << k << " ----\n";
cout << " ";
for(int i=1; i<=I; ++i) {
cout << setw(3) << V[i] << ' ';
}
cout << '\n';
cout << " ";
for(int i=1; i<=I; ++i) {
cout << '[' << setw(2) << i << ']';
}
cout << '\n';
for(int s=1; s<=S; ++s) {
cout << '[' << setw(2) << s << "] ";
for(int i=1; i<=I; ++i) {
if(maxsum[k](s, i) == -INF) {
cout << " ";
} else {
cout << setw(3) << maxsum[k](s, i) << ' ';
}
}
cout << '\n';
}
}
// output the indices belonging to the solution by working backward in the
// dynamic programming tables
int t_S = S;
int t_I = I;
for(int k=K; k>=1; --k) {
if(t_I <= 0 || t_S <= 0) {
cout << "error...\n";
break;
}
auto m = maxsum[k](t_S, t_I);
int i;
for(i=t_I; i>=1; --i) {
if(maxsum[k](t_S, i) != m)
break;
}
cout << "index: " << setw(3) << (i+1) << ' ';
cout << "sum: " << setw(3) << t_S << '\n';
t_I = i;
t_S = t_S - i - 1;
}
cout << "max sum: " << maxsum[K](S, I) << '\n';
}
关于algorithm - 指数总和为常量的最大总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46401814/
我基本上有三个表: hunt_c_usershunt_c_collected_eggshunt_c_achievements 我目前只使用 hunt_c_users 和 hunt_c_collecte
我已经计算了不同表中计数的总和。这会执行两次,每个 performanceID 一次。现在我想得到两个总和的总和。 下面是我目前做的两个总和的代码: SELECT SUM((COUNT (Bo
我有一个对 2 个值求和的脚本。我计划添加更多值(value),但首先我需要让它发挥作用。人们告诉我给他们 NUMBER 值,所以我这样做了,但现在它甚至没有给出输出。 base = 0; $("#F
我正在尝试计算在我们的数据库中跟踪的花费总额。每个订单文档包含一个字段“total_price” 我正在尝试使用以下代码: db.orders.aggregate({ $group: {
给定 Excel 2013(或更高版本)中的 2 个命名表: tbl发票 ID InvRef Total 1 I/123 45 2 I/234
希望你们一切都好。我来这里是因为我从今天早上开始就试图解决一个问题,我再也受不了了。 这就是上下文:我有一个 excel 工作簿,其中有不同的工作表,其中包含不同国家/地区的不同商业计划。我的目标是制
我有一份报告显示客户订购的产品及其价格: CompanyA Product 7 14.99 CompanyA Product 3 45.95 CompanyA Prod
我使用此python客户端: https://github.com/ryananguiano/python-redis-timeseries 如何汇总所有匹配? ts = TimeSeries(cli
希望创建一个总和和计数公式,该公式将自动调整以适应范围内插入的新行。 例如,如果我在单元格 D55 中有公式 =SUM(D17:D54)。每次我在该范围内插入新行时,我都需要更改公式的顶部范围来解释它
所以,我需要聚合日期相同的行。 到目前为止,我的代码返回以下内容: date value source 0 2018-04-08 15:52:26.1
我有数字输入 数量约为 30 我需要将它们全部汇总到一个字段 我拥有的在下面 查看:
您好,我正在尝试根据以下数据计算过去三个月中出现不止一次的不同帐户 ID 的数量;我想要 2 作为查询结果,因为 test1@gmail.com 和 test2@gmail.com 出现超过 1 次。
我有两个带有以下字段的表: ... orders.orderID orders.orderValue 和 payments.orderID payments.payVal 在 payments.pay
我想按 image_gallery 和 video_gallery 两列的 DESC 进行排序。 SELECT b.*, c.title as category, (S
实际上我的原始数据库为 SELECT sum(data1,data2) as database_value,sum(data3,data4) as database_not_value from t
我试图获取三个分数中每一个的值并将它们相加并显示在“总计:”中。我的问题是,我不知道如何做到这一点,以便每次其中一个分数值发生变化时,相应的总分值也会随之变化。 我可以在某处调用“onchange”来
如何获得按第一个值分组的元组列表中第二个和第三个值的总和? 即: list_of_tuples = [(1, 3, 1), (1, 2, 4), (2, 1, 0), (2, 2, 0)] expec
我正在尝试将我的列表中的整数转换为列表的总和和平均值,并说明任何低于冰点 F<32 的温度。每当我尝试获取总和或平均值时,我都会收到错误提示“+: 'int' 和 'str' 不支持的操作数类型”。我
在我的 ios 项目中,我使用了两个实体 (CoreData):具有一对多关系的 Person 和 Gifts 我知道如何计算给一个人的礼物总和: NSDecimalNumber *orderSum=
我有两个表(输入和类别): CREATE TABLE categories ( iId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, sNam
我是一名优秀的程序员,十分优秀!