关于一个算法问题,麻烦(200分)

  • 主题发起人 主题发起人 martinwang
  • 开始时间 开始时间
M

martinwang

Unregistered / Unconfirmed
GUEST, unregistred user!
有三个数字(170,180,215,数字不定),三个数字对应有不同的个数(170的有200个,180的有20个,215的有300个,个数不定),有一总数3648,<br>求:<br>&nbsp; &nbsp;根据三个数字及对应的个数组合成接近或大于3648最小的数如3648, 3649,列出所有的可能的组合,并将所有组合后每个数字的剩余值求出;<br>注意:<br>&nbsp; &nbsp;当每计算完一种组合后,每一次都求剩余组合的最小数,反复进行计算求解,直到达不到3648为止!!!!<br>&nbsp; &nbsp;现有代码:<br>&nbsp; iNum1, iNum2, iNum3: integer;//三个数<br>&nbsp; iCount1, iCount2, iCount3: integer;//三个数的每个的个数 &nbsp;<br>&nbsp; iCountAll: integer;//总数<br>procedure TForm1.btn1Click(Sender: TObject);<br><br><br>const<br>&nbsp; Msg = '当一数值[%s]经过计算的张数为:[%s]';<br>&nbsp; ValueEqual = '发现总数相等情况:数值1[%s](%s), 数值2[%s](%s),数值3[%s](%s)';<br>&nbsp; //ValueEqual = '发现总数相等情况:数值1[%s](%s)(剩余%s), 数值2[%s](%s)(剩余%s),数值3[%s](%s)(剩余%s)';<br>// &nbsp;ValueNotEqual = '发现总数没有相等情况,能获得的最小值是:%s, 数值1[%s](%s)(剩余%s), 数值2[%s](%s)(剩余%s),数值3[%s](%s)(剩余%s)';<br>&nbsp; ValueNotEqual = '发现总数没有相等情况,能获得的最小值是:%s, 数值1[%s](%s), 数值2[%s](%s),数值3[%s](%s)';<br>&nbsp; LeftMsg = '剩余数值1[%s](%s), 数值2[%s](%s), 数值3[%s](%s)';<br>var<br>&nbsp; iCount: integer;//个数<br>&nbsp; Count1, Count2, Count3: Integer;<br>&nbsp; i, j, k: integer;//计数器<br>&nbsp; ls, lsValue: TStringList;<br>&nbsp; iTmp, iMin: integer;<br>&nbsp; bResult: boolean;<br>&nbsp; strTmp: string;<br>&nbsp; iTotal: integer;<br>&nbsp; iTmpTotal: integer;<br>begin<br>&nbsp; try<br>&nbsp; &nbsp; ls := TstringList.Create;<br>&nbsp; &nbsp; lsValue := TStringList.Create;<br>&nbsp; &nbsp; bResult := False;<br>&nbsp; &nbsp; //先计算一个数为主的 <br>&nbsp; &nbsp; mmo1.Lines.Clear;<br>&nbsp; &nbsp; iTotal := iCountAll - &nbsp;StrToIntDef(edt1.Text, 0);<br>&nbsp; &nbsp; iTmpTotal := iCount1 * iNum1 + iCount2 * iNum2 + iCount3 * iNum3;<br>&nbsp; &nbsp; mmo1.Lines.Add('*******************开始计算********************');<br>&nbsp; &nbsp; mmo1.Lines.Add('*******************数值为:' + IntToStr(iCountAll) + '*********');<br>&nbsp; &nbsp; mmo1.Lines.Add('*******************起始值为:' + IntToStr(iTotal) + '*********');<br>&nbsp; &nbsp; iTmp := 0;<br>&nbsp; &nbsp; Count1 := iCount1;<br>&nbsp; &nbsp; Count2 := iCount2;<br>&nbsp; &nbsp; Count3 := iCount3;<br>&nbsp; &nbsp; iMin := 0;<br>&nbsp; &nbsp; while (iTmpTotal &gt; iTotal) do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; ls.Clear;<br>&nbsp; &nbsp; &nbsp; for i := 0 to iCount1 &nbsp;do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; for j := 0 to iCount2 &nbsp;do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for k := 0 to iCount3 &nbsp;do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((Count1 - i ) &lt; 0 ) or ((Count2 - j ) &lt; 0 ) or ((Count3 - k ) &lt; 0 ) then break;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iTmp := i * iNum1 + j * iNum2 + k * iNum3;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //如果有相等的情况<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if iTmp &lt; iTotal then Continue;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //if iTmpTotal &lt; iTotal then break;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Count1 &lt; 0) or (Count2 &lt; 0) or (Count3 &lt; 0) then break;<br><br><br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if iTmp = iTotal then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mmo1.Lines.Add(Format(ValueEqual, [IntToStr(iNum1), IntToStr(i),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IntToStr(iNum2), IntToStr(j), IntToStr(iNum3), IntToStr(k)]));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bResult := true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iTmpTotal := iTmpTotal - iTmp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count1 := Count1 - i;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count2 := Count2 - j;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count3 := Count3 - k;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //当算出的值大于总数时<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (iTmp &gt; iTotal) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ls.Sort;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (ls.Count = 0 ) or ((ls.Count &gt; 0) and (StrToInt(ls.Names[0]) &gt;= iTmp)) then//此处最小值取得有问题<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ls.Add(IntToStr(iTmp) + '=' + IntToStr(i) + ',' + IntToStr(j) + ',' + IntToStr(k));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iTmpTotal := iTmpTotal - iTmp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count1 := Count1 - i;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count2 := Count2 - j;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count3 := Count3 - k;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; if (ls.Count &gt; 0 ) {and (not bResult)}then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; ls.Sort;<br>&nbsp; &nbsp; &nbsp; &nbsp; lsValue.Delimiter := ',';<br>&nbsp; &nbsp; &nbsp; &nbsp; strtmp := ls.Names[0];<br>&nbsp; &nbsp; &nbsp; &nbsp; for i := 0 to &nbsp;ls.Count - 1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lsValue.DelimitedText := ls.ValueFromIndex;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if strtmp = ls.Names then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mmo1.Lines.Add(Format(ValueNotEqual, [ls.Names, IntToStr(iNum1), lsValue.Strings[0],<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IntToStr(iNum2), lsValue.Strings[1],<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IntToStr(iNum3), lsValue.Strings[2]]));<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count1 := Count1 + StrToInt(lsValue[0]);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count2 := Count2 + StrToInt(lsValue[1]);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Count3 := Count3 + StrToInt(lsValue[2]);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; iTmpTotal := iTmpTotal + StrToInt(ls.Names);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; mmo1.Lines.Add(Format(LeftMsg, [IntToStr(iNum1), IntToStr(Count1),<br>&nbsp; &nbsp; &nbsp; IntToStr(iNum2), IntToStr(Count2),IntToStr(iNum3), IntToStr(Count3)]));<br>&nbsp; &nbsp; mmo1.Lines.Add('*******************计算完成********************');<br>&nbsp; &nbsp; ShowMessage('计算完成');<br>&nbsp; finally<br>&nbsp; &nbsp; ls.Free;<br>&nbsp; &nbsp; lsValue.Free;<br>&nbsp; end;<br><br><br><br>end;
 
顶一下哦
 
俺的理解能力比较差,不清楚楼主的问题是什么?[:D]
 
你所求的每一次剩余组合的最小数是不是最接近3648的最大数
 
1元40张 &nbsp;5元20 &nbsp;10元10张 &nbsp; 要付30元 &nbsp;有多少种付法?
 
to zuodan:<br>&nbsp; &nbsp; 是的!!!但是现在还有一个问题,如前所述,有N多种组合可以形成大于3648的最小数!!!如(170的10, 180的20,215的10这里只是举例还有其他可能),但要保证你选的这种组合的顺序会使后面的运算的成本最低,也就是剩下的计算中大于3648的个数最多,且剩余的各个数的个数最少!!!其实这个问题是挺难解释的,所以很麻烦,看看大家有什么好方法没有,我觉得他象数据结构中的一些经典算法,但数据结构扔太久了,希望大家能帮上忙,顺便复习一下算法!!!<br>to DIGUA:<br>&nbsp; &nbsp;这个比较简单!是典型的百钱百鳮的问题!!!!上网搜一下就有了!!
 
哈哈,和楼主问题类似啊,只是楼主的问题比较晕<br>现在工作忙,有空帮你搞搞这个"大工程"<br>嘿嘿
 
后退
顶部