13,825
社区成员
发帖
与我相关
我的任务
分享
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//#include <list>
#include <stack>
#include <vector>
using namespace std;
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TEdit *Edit2;
TButton *Button2;
TMemo *Memo1;
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
public: // User declarations
struct FItem
{
AnsiString name; //名称
int Pro1;//属性1
int Pro2;//属性2
int Pro3;//属性3
};
vector<FItem> listscr;//原列表
stack<FItem> listans;//分析列表
// list<FItem>::iterator listitor;//迭代器
TStrings* ComList;//最终组合列表
int MaxSum;//属性3和的最大值
AnsiString sumName;//名称组合之和
int sumX, sumY, sumZ;//缓存当前x、y、z各自的属性和
__fastcall TForm1(TComponent* Owner);
bool __fastcall IsOK(stack<FItem> &list, int X, int Y);//判断是否满足XY条件
void __fastcall DelTop(stack<FItem> &list);//去掉最后入栈的属性累加
void __fastcall setMaxCond();//记录组合
void __fastcall Travel(stack<FItem> &list, int start, int X, int Y);//递归
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{//从文件中读取数据
ComList = new TStringList();
TStrings* s_list = new TStringList();
s_list->LoadFromFile(ExtractFilePath(Application->ExeName) + "data.txt");
for (int i = 0; i < s_list->Count; i++)
{
FItem *newitem = new FItem();
AnsiString str = s_list->Strings[i];
int flg = str.Pos("\t");
newitem->name = str.SubString(1, flg-1);
str.Delete(1, flg);
flg = str.Pos("\t");
newitem->Pro1 = StrToInt(str.SubString(1, flg-1));
str.Delete(1, flg);
flg = str.Pos("\t");
newitem->Pro2 = StrToInt(str.SubString(1, flg-1));
str.Delete(1, flg);
newitem->Pro3 = StrToInt(str);
listscr.push_back(*newitem);
}
delete s_list;
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::IsOK(stack<FItem> &list, int X, int Y)//判断是否满足XY条件
{
FItem newitem = list.top();
sumX += newitem.Pro1;
sumY += newitem.Pro2;
if(sumX > X || sumY > Y)//不符合情况时立刻减去属性1、2的累加值
{
sumX -= newitem.Pro1;
sumY -= newitem.Pro2;
return false;
}
else//符合情况时将名称和属性3也累加进来
{
sumName += newitem.name; // + "\t"
sumZ += newitem.Pro3;
return true;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DelTop(stack<FItem> &list)
{
FItem newitem = list.top();
// sumName.Delete(sumName.Length() - newitem.name.Length(), newitem.name.Length())
sumName.Delete(sumName.Length(), 1);
sumX -= newitem.Pro1;
sumY -= newitem.Pro2;
sumZ -= newitem.Pro3;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::setMaxCond()
{
if(sumZ > MaxSum)//刷新纪录
{
ComList->Clear();
ComList->Add(sumName);
MaxSum = sumZ;
}
else if(sumZ == MaxSum)//增加并列纪录
ComList->Add(sumName);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Travel(stack<FItem> &list, int start, int X, int Y)//递归
{
for (int i = start; i < listscr.size(); i++)
{
list.push(listscr[i]);
if(IsOK(list, X, Y))//判断是否满足XY条件
{
Travel(list, i, X, Y); //递归,断续加入更多物品
}
else//只有叠加到极限时才比较记录(目前所有属性都是正数)
{
list.pop();
setMaxCond();
}
if(list.size() > 0)
{
DelTop(list);
list.pop();
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)//调用
{
ComList->Clear();
MaxSum = 0;
sumName = "";
sumX = 0;
sumY = 0;
sumZ = 0;
Travel(listans, 0, Edit1->Text.ToInt(), Edit2->Text.ToInt());
Memo1->Lines->Assign(ComList); //打印结果
}
//---------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;
struct TObj{
char name;
int prop1;
int prop2;
int prop3;
};
struct TGroup{
vector<int> vecObj; // 物品组合(索引)
int nX; // 属性1剩余点数
int nY; // 属性2剩余点数
int nSumZ; // 属性3总和
};
// 参数:物品数组objlist、物品数组大小n,临时组合grp,新加物品的起始索引i,属性3的最大组合maxgrp
void travel(const TObj *objlist, const int n, TGroup &grp, int i, TGroup &maxgrp)
{
//下面两行输出所有组合,确认是否有重复组合出现
//copy(grp.vecObj.begin(), grp.vecObj.end(), ostream_iterator<int>(cout));
//cout << "\t nX: " << grp.nX << ";nY " << grp.nY << ";nSumZ: " << grp.nSumZ << endl;
for(; i<n; ++i)
{
const TObj & obj = objlist[i];
if(grp.nX >= obj.prop1 && grp.nY >= obj.prop2)// 剩余点数足够
{
// 加入当前物品索引
grp.vecObj.push_back(i);
grp.nX -= obj.prop1;
grp.nY -= obj.prop2;
grp.nSumZ += obj.prop3;
// 抽取最大组合
if(maxgrp.nSumZ < grp.nSumZ) maxgrp = grp;
// 继续尝试
travel(objlist, n, grp, i, maxgrp);
// 恢复
grp.vecObj.pop_back();
grp.nX += obj.prop1;
grp.nY += obj.prop2;
grp.nSumZ -= obj.prop3;
}
}
}
TObj g_objs[6]={
{'A',100,10,10},
{'B',200,21,21},
{'C',300,33,35},
{'D',400,42,48},
{'E',500,56,60},
{'F',600,65,81}
};
int main(int argc, char* argv[])
{
// 临时组合初始值
TGroup grp;
grp.nX = 10000;
grp.nY = 1000;
grp.nSumZ = 0;
// 最大组合
TGroup maxgrp=grp;
travel(g_objs, 6, grp, 0, maxgrp);
// 输出结果
for(vector<int>::const_iterator itr=maxgrp.vecObj.begin();
itr!=maxgrp.vecObj.end();
++itr)
{
cout << g_objs[*itr].name << ' ';
}
cout << endl << "属性1总和:" << 10000 - maxgrp.nX << endl;
cout << "属性2总和:" << 1000 - maxgrp.nY << endl;
cout << "属性3总和:" << maxgrp.nSumZ << endl;
// 暂停
cin.get();
return 0;
}
else//只有叠加到极限时才比较记录(目前所有属性都是正数)
{
list.pop();
setMaxCond();
}
if(list.size() > 0)
{
DelTop(list);
list.pop();
}
travel(stack &s, int start)
{
for(int i=start; i<300; i++)
{
s.push(obj[i]); //加入第i件物品
if(IsOK(s)) // 如果条件符合
{
travel(s, i); // 递归,断续加入更多物品
}
else //只有叠加到极限时才比较记录(前提是属性3没有负数)
{
s.pop();
setMaxCond(s); // 如果s里的属性3之和最大,就记录之
}
s.pop();
}
}
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <list>
#include <vector>
using namespace std;
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *Edit1;
TEdit *Edit2;
TButton *Button2;
TMemo *Memo1;
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
public: // User declarations
struct FItem
{
AnsiString name; //名称
int Pro1;//属性1
int Pro2;//属性2
int Pro3;//属性3
};
vector<FItem> listscr;//原列表
list<FItem> listans;//分析列表
list<FItem>::iterator listitor;//迭代器
TStrings* ComList;//最终组合列表
int MaxSum;//属性3和的最大值
__fastcall TForm1(TComponent* Owner);
bool __fastcall IsOK(list<FItem> &list, int X, int Y);//判断是否满足XY条件
bool __fastcall Travel(list<FItem> &list, int X, int Y);//递归
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{//从文件中读取数据
ComList = new TStringList();
TStrings* s_list = new TStringList();
s_list->LoadFromFile(ExtractFilePath(Application->ExeName) + "data.txt");
for (int i = 0; i < s_list->Count; i++)
{
FItem *newitem = new FItem();
AnsiString str = s_list->Strings[i];
int flg = str.Pos("\t");
newitem->name = str.SubString(1, flg-1);
str.Delete(1, flg);
flg = str.Pos("\t");
newitem->Pro1 = StrToInt(str.SubString(1, flg-1));
str.Delete(1, flg);
flg = str.Pos("\t");
newitem->Pro2 = StrToInt(str.SubString(1, flg-1));
str.Delete(1, flg);
newitem->Pro3 = StrToInt(str);
listscr.push_back(*newitem);
}
delete s_list;
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::IsOK(list<FItem> &list, int X, int Y)//判断是否满足XY条件
{
AnsiString sumName = "";
int sumX = 0;
int sumY = 0;
int sumZ = 0;
for (listitor = list.begin(); listitor != list.end(); ++listitor)
{
FItem newitem = *listitor;
sumName += newitem.name; // + "\t"
sumX += newitem.Pro1;
sumY += newitem.Pro2;
sumZ += newitem.Pro3;
if(sumX > X || sumY > Y)
return false;
}
if(sumZ > MaxSum)//刷新纪录
{
ComList->Clear();
ComList->Add(sumName);
MaxSum = sumZ;
}
else if(sumZ == MaxSum)//增加并列纪录
ComList->Add(sumName);
return true;
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::Travel(list<FItem> &list, int X, int Y)//递归
{
for (int i = 0; i < listscr.size(); i++)
{
list.push_back(listscr[i]);
if(IsOK(list, X, Y))//判断是否满足XY条件
Travel(list, X, Y); //递归,断续加入更多物品
list.pop_back();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)//调用
{
ComList->Clear();
MaxSum = 0;
Travel(listans, Edit1->Text.ToInt(), Edit2->Text.ToInt());
Memo1->Lines->Assign(ComList); //显示结果
}
// 用堆栈stack来保存物品的组合
bool IsOK(const stack& ); //判断 属性1之和<X and 属性2之和<Y
travel(stack &s)
{
for(int i=0; i<300; i++)
{
s.push(obj[i]); //加入第i件物品
if(IsOK(s)) // 如果条件符合
{
setMaxCond(s); // 如果s里的属性3之和最大,就记录之
travel(s); // 递归,断续加入更多物品
}
s.pop(); //测试完成后取出前面加入的第i件物品(换下一件)
}
}