poj1010解题报告

纠结一个下午,发现自己真的是越来越菜了,以前做的很快的题竟然久战不下!以后得在poj上常练了!

以下是源码,比较乱,难得整理了……回溯法的应用

 
  
#include < iostream >
#include
< fstream >
using namespace std;
const int MAX = 1000 ;
int typeValue[MAX];
int x[MAX]; // 每种对应的张数,回溯时用
int xx[MAX];
int Request[MAX];
int maxKind = 0 ;
int totalStemps = 100000 ;
int maxValue = 0 ;
bool isTie = false ;
int CurrentKind = 0 ;
int CurrentTotalStamps = 0 ;
int CurrentMaxValue = 0 ;
int typeNum = 0 ;
int requestNum = 0 ;
int CurrentRequest = 0 ;
void f( int n, int currentSum, int * x);
// 在当前和为currentSum,剩余最大和为leftsum的前提下,第n
// 种面值邮票的选择情况,选择张数结果存放在x[n-1]中
int main()
{
ifstream cin(
" in.txt " );
ofstream cout(
" out.txt " );
int temp = 0 ;
while (cin >> temp)
{

typeNum
= 0 ;
requestNum
= 0 ;
if (temp != 0 )
{
typeValue[typeNum
++ ] = temp;
}


while ((cin >> temp,temp) != 0 )
{
typeValue[typeNum
++ ] = temp;
}
while ((cin >> temp,temp) != 0 )
{
Request[requestNum
++ ] = temp;
}

for ( int t = 0 ;t < requestNum;t ++ )
{

maxKind
= 0 ;
totalStemps
= 100000 ;
maxValue
= 0 ;
isTie
= false ;
memset(x,
0 ,MAX * sizeof ( int ));
memset(xx,
0 ,MAX * sizeof ( int ));
int currentSum = 0 ;
CurrentRequest
= Request[t];
CurrentKind
= 0 ;
CurrentTotalStamps
= 0 ;
CurrentMaxValue
= 0 ;
f(
0 ,currentSum,x);
if (maxKind == 0 )
{
cout
<< Request[t] << " ---- none " ;
}
else
{
if (isTie)
{
cout
<< Request[t] << " ( " << maxKind << " ): tie " ;
}
else
{
cout
<< Request[t] << " ( " << maxKind << " ): " ;
for ( int k = 0 ;k < typeNum;k ++ )
{
if (xx[k] > 0 )
{
for ( int count = 0 ;count < xx[k];count ++ )
{
if (count == xx[k] - 1 )
{
cout
<< typeValue[k];
}
else
{
cout
<< typeValue[k] << " " ;
}
}
if (k != typeNum - 1 )
{
cout
<< " " ;
}

}

}

}
}
cout
<< " \n " ;
}

}
return 0 ;

}
void f( int n, int currentSum, int * x)
{
int m = 0 ;
if (n >= typeNum)
{
if (currentSum == CurrentRequest)
{
if (CurrentKind > maxKind)
{
maxKind
= CurrentKind;
totalStemps
= CurrentTotalStamps;
maxValue
= CurrentMaxValue;
isTie
= false ;
for ( m = 0 ;m < typeNum;m ++ )
{
xx[m]
= x[m];
}
}
else if (CurrentKind == maxKind)
{
if (CurrentTotalStamps < totalStemps)
{
totalStemps
= CurrentTotalStamps;
maxValue
= CurrentMaxValue;
isTie
= false ;
for ( m = 0 ;m < typeNum;m ++ )
{
xx[m]
= x[m];
}
}
else if (CurrentTotalStamps == totalStemps)
{
if (CurrentMaxValue > maxValue)
{
maxValue
= CurrentMaxValue;
for ( m = 0 ;m < typeNum;m ++ )
{
xx[m]
= x[m];
}
isTie
= false ;
}
else if (CurrentMaxValue == maxValue)
{
isTie
= true ;

}
}

}
}
return ;
}
else
{
for (x[n] = 0 ;x[n] <= ( 4 - CurrentTotalStamps);x[n] ++ )
{

int temp1 = CurrentMaxValue;
if ((currentSum + x[n] * typeValue[n]) <= CurrentRequest)
{

if ( x[n] != 0 )
CurrentKind
++ ;
if (x[n] != 0 && typeValue[n] > CurrentMaxValue) // 必须加上x[n]!=0 ,因为对于4=3+1+0
// (某种票不选的情况)和(3,1)相比,不能更新最大值,因为没有选则,但搜索时会出现这种情况
{
CurrentMaxValue
= typeValue[n];
}
CurrentTotalStamps
+= x[n];
f(n
+ 1 ,currentSum + x[n] * typeValue[n],x);
if ( x[n] != 0 )
CurrentKind
-- ;
CurrentMaxValue
= temp1;
CurrentTotalStamps
-= x[n];
}
}

}

}

转载于:https://www.cnblogs.com/easyFancy/archive/2011/06/04/2072857.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值