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];
}
}
}
}