51,391
社区成员




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bagItemsTest
{
class Program
{
static void Main(string[] args)
{
int[] a = { 55000, 55000, 63500, 96120, 97000, 102350, 102350, 132510, 135370, 140000, 144000, 166800, 167530, 169800, 178300, 178300, 178800, 179300, 181000, 181000, 181000, 181000, 181000, 181000, 181000, 182200, 183500, 185684, 188800, 188800, 189800, 190800, 190800, 190800, 195684, 198000, 199626, 199626, 199800, 199800, 199900, 201000, 208700, 209800, 209800, 209800, 209800, 209800, 219000, 219000, 219000, 219000, 219800, 220000, 220000, 220000, 220130, 225600, 228000, 228000, 229434, 229800, 229800, 229800, 229800, 235000, 238800, 240000, 240900, 244800, 247800, 248000, 249800, 249800, 249800, 249800, 249800, 249800, 249800, 249800, 250000, 250000, 250000, 250000, 257000, 260800, 279800, 279800, 279800, 279800, 280340, 285000, 295000, 295000, 295000, 298000, 299000, 300000, 300000, 300000, 313701, 328897, 337300, 345000, 350000, 350000, 350000, 350064, 350064, 350064, 350064, 350064, 429800, 430290, 440154, 472200, 472200, 487305, 500500, 506300, 512226, 544110, 749000, 820000, 1100000 };
List<int> ar = a.ToList<int>();
List<int> r = getRresult(ar, 21, 6531127);
}
static Dictionary<int, List<int>> cache = new Dictionary<int, List<int>>();
static long n = 0;
static int m = 0;
//在ar里返回count个数字,使其结果相加=sum
private static List<int> getRresult(List<int> ar, int count, int sum)
{
n++;
if (ar.Count <= 0 || count <= 0 || sum < 55000 || ar.Count < count || sum < count * 55000)
{
return null;
}
int key = (ar.Count.ToString() + count.ToString() + sum.ToString()).GetHashCode();
if (cache.ContainsKey(key))
{
m++;
return cache[key];
}
if (ar.Count == 1 && ar[0] != sum)//只有一个并且不等和
{
return null;
}
if (ar.Count == 1 && ar[0] == sum)
{
return ar;
}
//判断最后一个数字加还是不加入
int i = ar[ar.Count - 1];
List<int> nar2 = new List<int>();
nar2.AddRange(ar);
nar2.Remove(i);//除去最后一个数字
int ncount = count - 1;
int nsum = sum - i;
if (nar2.Count <= 0 || ncount <= 0 || nsum < 55000 || nar2.Count < ncount || sum < count * 55000)//没有了就返回0以结束递归
{
List<int> nar4 = new List<int>();
nar4.AddRange(ar);
nar4.Remove(i);//加入这一个不行,则移除
return getRresult(nar4, count, sum);
}
List<int> nar3 = getRresult(nar2, ncount, nsum);
key = (nar2.Count.ToString() + ncount.ToString() + nsum.ToString()).GetHashCode();
if (!cache.ContainsKey(key))
{
cache.Add(key, nar3);
}
if (nar3 == null)
{
List<int> nar4 = new List<int>();
nar4.AddRange(ar);
nar4.Remove(i);//加入这一个不行,则移除
return getRresult(nar4, count, sum);
}
else
nar3.Add(i);
if (nar3.Count != count)//结果等于但个数不等于
{
List<int> nar4 = new List<int>();
nar4.AddRange(ar);
nar4.Remove(i);//加入这一个不行,则移除
return getRresult(nar4, count, sum);
}
return nar3;
}
}
}
楼主看一下这个行不?速度上似乎比上面的大神要快点,内存占用上也更小点,如果把list和Dictionary换成数组速度应该会更快些,
#include <iostream>
#include <functional>
#include <algorithm>
#define SIZE 125
#define MAX 6531127
using namespace std;
static int input[SIZE] = { 55000, 55000, 63500, 96120, 97000,
102350, 102350, 132510, 135370, 140000,
144000, 166800, 167530, 169800, 178300,
178300, 178800, 179300, 181000, 181000,
181000, 181000, 181000, 181000, 181000,
182200, 183500, 185684, 188800, 188800,
189800, 190800, 190800, 190800, 195684,
198000, 199626, 199626, 199800, 199800,
199900, 201000, 208700, 209800, 209800,
209800, 209800, 209800, 219000, 219000,
219000, 219000, 219800, 220000, 220000,
220000, 220130, 225600, 228000, 228000,
229434, 229800, 229800, 229800, 229800,
235000, 238800, 240000, 240900, 244800,
247800, 248000, 249800, 249800, 249800,
249800, 249800, 249800, 249800, 249800,
250000, 250000, 250000, 250000, 257000,
260800, 279800, 279800, 279800, 279800,
280340, 285000, 295000, 295000, 295000,
298000, 299000, 300000, 300000, 300000,
313701, 328897, 337300, 345000, 350000,
350000, 350000, 350064, 350064, 350064,
350064, 350064, 429800, 430290, 440154,
472200, 472200, 487305, 500500, 506300,
512226, 544110, 749000, 820000, 1100000 }, goal_select = 21;
static struct _set
{
char _num_sum[5], _select[5][21];
int rep;
}bag1[MAX + 1], bag2[MAX + 1], *tmp, *dp1, *dp2;
void Print_Select(struct _set *goal,const int rep)
{
int pos_stop = goal[MAX]._num_sum[rep];
cout << "The items are :" << endl;
for (int i = 0; i < pos_stop; i++)
cout << goal[MAX]._select[rep][i] + 1 << ": " << input[goal[MAX]._select[rep][i]] << endl;
}
void Copy(const int m1, const int m2)
{
memcpy(dp2[m2]._num_sum, dp1[m1]._num_sum, sizeof(dp2[m2]._num_sum));
memcpy(dp2[m2]._select, dp1[m1]._select, sizeof(dp2[m2]._select));
dp2[m2].rep = dp1[m1].rep;
}
int Max(const int x, const int y)
{
return x > y ? x : y;
}
void Merge_Bound(struct _set *pos1, struct _set *pos2, struct _set *goal,const int stuff)
{
int ptr_dp1 = 0, ptr_dp2 = 0, tmp_sum, tmp_rep = 0;
int up_bound = Max(pos1->_num_sum[pos1->rep - 1], pos2->_num_sum[pos2->rep - 1]) + 1;
for (int i = 1; i <= up_bound; i++)
{
if (pos1->rep != 0//0代表不合法
&& (pos1->_num_sum)[ptr_dp1] + 1 <= goal_select - 1
&& (pos1->_num_sum)[ptr_dp1] + 1 == i)
{
(goal->_num_sum)[tmp_rep] = tmp_sum = (pos1->_num_sum)[ptr_dp1] + 1;
memcpy((goal->_select)[tmp_rep], (pos1->_select)[ptr_dp1], sizeof((goal->_select)[tmp_rep]));
(goal->_select)[tmp_rep][tmp_sum - 1] = stuff - 1;
ptr_dp1++;
tmp_rep++;
}
else if (pos2->rep != 0
&& (pos2->_num_sum)[ptr_dp2] == i)
{
(goal->_num_sum)[tmp_rep] = (pos2->_num_sum)[ptr_dp2];
memcpy((goal->_select)[tmp_rep], (pos2->_select)[ptr_dp2], sizeof((pos2->_select)[ptr_dp2]));
ptr_dp2++;
tmp_rep++;
}
}
goal->rep = tmp_rep;
}
bool Search(void)
{
int pos, num_sum;
dp1[0].rep = 1;
for (int i = 1; i <= SIZE; i++)
{
dp2[0].rep = 1;
for (int j = 1; j < input[i - 1]; j++)
Copy(j, j);
for (int j = input[i - 1]; j <= MAX; j++)
{
if (j == MAX && dp1[MAX - input[i - 1]]._num_sum[dp1[MAX - input[i - 1]].rep - 1] + 1 == goal_select)//直接输出
{
Copy(MAX - input[i - 1], MAX);
pos = dp1[MAX - input[i - 1]].rep - 1;
dp2[MAX]._num_sum[pos]++;
num_sum = dp2[MAX]._num_sum[pos];
dp2[MAX]._select[pos][num_sum - 1] = i - 1;
Print_Select(dp2, dp2[MAX].rep - 1);
return true;
}
Merge_Bound(&dp1[j - input[i - 1]], &dp1[j], &dp2[j], i);
}
tmp = dp1; dp1 = dp2; dp2 = tmp;
}
return false;
}
int main(void)
{
dp1 = bag1; dp2 = bag2;
memset(dp1, 0, sizeof(dp1));
memset(dp2, 0, sizeof(dp2));
sort(input, input + SIZE);
if (Search())
cout << "SUCCESS" << endl;
else
cout << "FAIL" << endl;
system("pause");
return EXIT_SUCCESS;
}
#include <iostream>
#include <functional>
#include <algorithm>
#define SIZE 125
#define MAX 6531127
using namespace std;
static int input[SIZE] = { 55000, 55000, 63500, 96120, 97000,
102350, 102350, 132510, 135370, 140000,
144000, 166800, 167530, 169800, 178300,
178300, 178800, 179300, 181000, 181000,
181000, 181000, 181000, 181000, 181000,
182200, 183500, 185684, 188800, 188800,
189800, 190800, 190800, 190800, 195684,
198000, 199626, 199626, 199800, 199800,
199900, 201000, 208700, 209800, 209800,
209800, 209800, 209800, 219000, 219000,
219000, 219000, 219800, 220000, 220000,
220000, 220130, 225600, 228000, 228000,
229434, 229800, 229800, 229800, 229800,
235000, 238800, 240000, 240900, 244800,
247800, 248000, 249800, 249800, 249800,
249800, 249800, 249800, 249800, 249800,
250000, 250000, 250000, 250000, 257000,
260800, 279800, 279800, 279800, 279800,
280340, 285000, 295000, 295000, 295000,
298000, 299000, 300000, 300000, 300000,
313701, 328897, 337300, 345000, 350000,
350000, 350000, 350064, 350064, 350064,
350064, 350064, 429800, 430290, 440154,
472200, 472200, 487305, 500500, 506300,
512226, 544110, 749000, 820000, 1100000 }, goal_select = 21;
static struct _set
{
char _num_sum[5], _select[5][21];
int rep;
}bag1[MAX + 1], bag2[MAX + 1], *tmp, *dp1, *dp2;
void Print_Select(struct _set *goal,const int rep)
{
int pos_stop = goal[MAX]._num_sum[rep];
cout << "The items are :" << endl;
for (int i = 0; i < pos_stop; i++)
cout << goal[MAX]._select[rep][i] + 1 << ": " << input[goal[MAX]._select[rep][i]] << endl;
}
void Copy(const int m1, const int m2)
{
memcpy(dp2[m2]._num_sum, dp1[m1]._num_sum, sizeof(dp2[m2]._num_sum));
memcpy(dp2[m2]._select, dp1[m1]._select, sizeof(dp2[m2]._select));
dp2[m2].rep = dp1[m1].rep;
}
int Max(const int x, const int y)
{
return x > y ? x : y;
}
void Merge_Bound(struct _set *pos1, struct _set *pos2, struct _set *goal,const int stuff)
{
int ptr_dp1 = 0, ptr_dp2 = 0, tmp_sum, tmp_rep = 0;
int up_bound = Max(pos1->_num_sum[pos1->rep - 1], pos2->_num_sum[pos2->rep - 1]) + 1;
for (int i = 1; i <= up_bound; i++)
{
if (pos1->rep != 0//0代表不合法
&& (pos1->_num_sum)[ptr_dp1] + 1 <= goal_select - 1
&& (pos1->_num_sum)[ptr_dp1] + 1 == i)
{
(goal->_num_sum)[tmp_rep] = tmp_sum = (pos1->_num_sum)[ptr_dp1] + 1;
memcpy((goal->_select)[tmp_rep], (pos1->_select)[ptr_dp1], sizeof((goal->_select)[tmp_rep]));
(goal->_select)[tmp_rep][tmp_sum - 1] = stuff - 1;
ptr_dp1++;
tmp_rep++;
}
else if (pos2->rep != 0
&& (pos2->_num_sum)[ptr_dp2] == i)
{
(goal->_num_sum)[tmp_rep] = (pos2->_num_sum)[ptr_dp2];
memcpy((goal->_select)[tmp_rep], (pos2->_select)[ptr_dp2], sizeof((pos2->_select)[ptr_dp2]));
ptr_dp2++;
tmp_rep++;
}
}
goal->rep = tmp_rep;
}
bool Search(void)
{
int pos, num_sum;
dp1[0].rep = 1;
for (int i = 1; i <= SIZE; i++)
{
dp2[0].rep = 1;
for (int j = 1; j < input[i - 1]; j++)
Copy(j, j);
for (int j = input[i - 1]; j <= MAX; j++)
{
if (j == MAX && dp1[MAX - input[i - 1]]._num_sum[dp1[MAX - input[i - 1]].rep - 1] + 1 == goal_select)//直接输出
{
Copy(MAX - input[i - 1], MAX);
pos = dp1[MAX - input[i - 1]].rep - 1;
dp2[MAX]._num_sum[pos]++;
num_sum = dp2[MAX]._num_sum[pos];
dp2[MAX]._select[pos][num_sum - 1] = i - 1;
Print_Select(dp2, dp2[MAX].rep - 1);
return true;
}
Merge_Bound(&dp1[j - input[i - 1]], &dp1[j], &dp2[j], i);
}
tmp = dp1; dp1 = dp2; dp2 = tmp;
}
return false;
}
int main(void)
{
dp1 = bag1; dp2 = bag2;
memset(dp1, 0, sizeof(dp1));
memset(dp2, 0, sizeof(dp2));
sort(input, input + SIZE);
if (Search())
cout << "SUCCESS" << endl;
else
cout << "FAIL" << endl;
system("pause");
return EXIT_SUCCESS;
}
#include <iostream>
#include <functional>
#include <algorithm>
#define SIZE 125
#define MAX 6531127
using namespace std;
static int input[SIZE] = { 55000, 55000, 63500, 96120, 97000,
102350, 102350, 132510, 135370, 140000,
144000, 166800, 167530, 169800, 178300,
178300, 178800, 179300, 181000, 181000,
181000, 181000, 181000, 181000, 181000,
182200, 183500, 185684, 188800, 188800,
189800, 190800, 190800, 190800, 195684,
198000, 199626, 199626, 199800, 199800,
199900, 201000, 208700, 209800, 209800,
209800, 209800, 209800, 219000, 219000,
219000, 219000, 219800, 220000, 220000,
220000, 220130, 225600, 228000, 228000,
229434, 229800, 229800, 229800, 229800,
235000, 238800, 240000, 240900, 244800,
247800, 248000, 249800, 249800, 249800,
249800, 249800, 249800, 249800, 249800,
250000, 250000, 250000, 250000, 257000,
260800, 279800, 279800, 279800, 279800,
280340, 285000, 295000, 295000, 295000,
298000, 299000, 300000, 300000, 300000,
313701, 328897, 337300, 345000, 350000,
350000, 350000, 350064, 350064, 350064,
350064, 350064, 429800, 430290, 440154,
472200, 472200, 487305, 500500, 506300,
512226, 544110, 749000, 820000, 1100000 }, goal_select = 21;
static struct _set
{
char _num_sum[5], _select[5][21];
int rep;
}bag1[MAX + 1], bag2[MAX + 1], *tmp, *dp1, *dp2;
void Print_Select(struct _set *goal,const int rep)
{
int pos_stop = goal[MAX]._num_sum[rep];
cout << "The items are :" << endl;
for (int i = 0; i < pos_stop; i++)
cout << goal[MAX]._select[rep][i] + 1 << ": " << input[goal[MAX]._select[rep][i]] << endl;
}
void Copy(const int m1, const int m2)
{
memcpy(dp2[m2]._num_sum, dp1[m1]._num_sum, sizeof(dp2[m2]._num_sum));
memcpy(dp2[m2]._select, dp1[m1]._select, sizeof(dp2[m2]._select));
dp2[m2].rep = dp1[m1].rep;
}
int Max(const int x, const int y)
{
return x > y ? x : y;
}
void Merge_Bound(struct _set *pos1, struct _set *pos2, struct _set *goal,const int stuff)
{
int ptr_dp1 = 0, ptr_dp2 = 0, tmp_sum, tmp_rep = 0;
int up_bound = Max(pos1->_num_sum[pos1->rep - 1], pos2->_num_sum[pos2->rep - 1]) + 1;
for (int i = 1; i <= up_bound; i++)
{
if (pos1->rep != 0//0代表不合法
&& (pos1->_num_sum)[ptr_dp1] + 1 <= goal_select - 1
&& (pos1->_num_sum)[ptr_dp1] + 1 == i)
{
(goal->_num_sum)[tmp_rep] = tmp_sum = (pos1->_num_sum)[ptr_dp1] + 1;
memcpy((goal->_select)[tmp_rep], (pos1->_select)[ptr_dp1], sizeof((goal->_select)[tmp_rep]));
(goal->_select)[tmp_rep][tmp_sum - 1] = stuff - 1;
ptr_dp1++;
tmp_rep++;
}
else if (pos2->rep != 0
&& (pos2->_num_sum)[ptr_dp2] == i)
{
(goal->_num_sum)[tmp_rep] = (pos2->_num_sum)[ptr_dp2];
memcpy((goal->_select)[tmp_rep], (pos2->_select)[ptr_dp2], sizeof((pos2->_select)[ptr_dp2]));
ptr_dp2++;
tmp_rep++;
}
}
goal->rep = tmp_rep;
}
bool Search(void)
{
int pos, num_sum;
dp1[0].rep = 1;
for (int i = 1; i <= SIZE; i++)
{
dp2[0].rep = 1;
for (int j = 1; j < input[i - 1]; j++)
Copy(j, j);
for (int j = input[i - 1]; j <= MAX; j++)
{
if (j == MAX && dp1[MAX - input[i - 1]]._num_sum[dp1[MAX - input[i - 1]].rep - 1] + 1 == goal_select)//直接输出
{
Copy(MAX - input[i - 1], MAX);
pos = dp1[MAX - input[i - 1]].rep - 1;
dp2[MAX]._num_sum[pos]++;
num_sum = dp2[MAX]._num_sum[pos];
dp2[MAX]._select[pos][num_sum - 1] = i - 1;
Print_Select(dp2, dp2[MAX].rep - 1);
return true;
}
Merge_Bound(&dp1[j - input[i - 1]], &dp1[j], &dp2[j], i);
}
tmp = dp1; dp1 = dp2; dp2 = tmp;
}
return false;
}
int main(void)
{
dp1 = bag1; dp2 = bag2;
memset(dp1, 0, sizeof(dp1));
memset(dp2, 0, sizeof(dp2));
sort(input, input + SIZE);
if (Search())
cout << "SUCCESS" << endl;
else
cout << "FAIL" << endl;
system("pause");
return EXIT_SUCCESS;
}
#include <iostream>
#include <functional>
#include <algorithm>
#define SIZE 10
#define MAX 16
using namespace std;
static int input[SIZE] = { 1,3,5,7,9,11,13,15,17,19 }, goal_select = 2;
static struct _set
{
int _num_sum, _select[10];
}bag[2][MAX + 1], *dp1, *dp2, *tmp;
void Print_Select(struct _set *goal)
{
cout << "The items are !" << endl;
for (int i = 0; i < goal[MAX]._num_sum; i++)
cout << goal[MAX]._select[i] + 1 << ": " << input[goal[MAX]._select[i]] << endl;
}
bool Search(void)
{
int tmp_sum;
dp1 = bag[0], dp2 = bag[1];
bag[0][0]._num_sum = 0;
for (int i = 1; i <= MAX; i++)
dp1[i]._num_sum = -1;
for (int i = 1; i <= SIZE; i++)
{
dp2[0]._num_sum = 0;
for (int j = 1; j < input[i - 1]; j++)
{
dp2[j]._num_sum = tmp_sum = dp1[j]._num_sum;
memcpy(dp2[j]._select, dp1[j]._select, sizeof(dp2[j]._select));
}
for (int j = input[i - 1]; j <= MAX; j++)
{
if (dp1[j - input[i - 1]]._num_sum<goal_select)
{
if (dp1[j - input[i - 1]]._num_sum != -1
&& (dp1[j - input[i - 1]]._num_sum + 1>dp1[j]._num_sum))
{
dp2[j]._num_sum = tmp_sum = dp1[j - input[i - 1]]._num_sum + 1;
memcpy(dp2[j]._select, dp1[j - input[i - 1]]._select, sizeof(dp2[j]._select));
dp2[j]._select[tmp_sum - 1] = i - 1;
}
else
{
dp2[j]._num_sum = tmp_sum = dp1[j]._num_sum;
memcpy(dp2[j]._select, dp1[j]._select, sizeof(dp2[j]._select));
}
}
else if (dp1[j - input[i - 1]]._num_sum >= goal_select)
{
if (dp1[j - input[i - 1]]._num_sum != -1
&& (dp1[j - input[i - 1]]._num_sum + 1< dp1[j]._num_sum))
{
dp2[j]._num_sum = tmp_sum = dp1[j - input[i - 1]]._num_sum + 1;
memcpy(dp2[j]._select, dp1[j - input[i - 1]]._select, sizeof(dp2[j]._select));
dp2[j]._select[tmp_sum - 1] = i - 1;
}
else
{
dp2[j]._num_sum = tmp_sum = dp1[j]._num_sum;
memcpy(dp2[j]._select, dp1[j]._select, sizeof(dp2[j]._select));
}
}
if (dp2[MAX]._num_sum == goal_select)
{
Print_Select(dp2);
return true;
}
}
tmp = dp1; dp1 = dp2; dp2 = tmp;
}
return false;
}
int main(void)
{
memset(bag, 0, sizeof(bag));
sort(input, input + SIZE);
if (Search())
cout << "SUCCESS" << endl;
else
cout << "FAIL" << endl;
system("pause");
return EXIT_SUCCESS;
}
用C++写的,不知道可不可以,就是01背包改一改的,楼主给的例子是一定能找到的吗?