这道题大神解释得很清楚,包括我根本没有意识到的优化(同面额的邮票种类大于5的情况解是一样的)。我一开始也是按照递归深搜做的,效果比较差,应该是剪枝的地方没有考虑情况。这道题剪枝同时考虑效率和正确性还是比较难的。后来按照最直观的四重循环做的。因为邮票组合最多四种。
具体分析可以移步大神的解题报告:http://blog.csdn.net/cugbliang/article/details/2742242
代码写得比较繁琐,重复代码比较多。另外,对STL中的vector实现还是不清楚,具体来说就是clear()和resize()在windows下用visual studio 2010 sp1 ultimate环境下运行有时会抛异常,我到后来还是没弄清楚为什么。不过程序在linux下用gcc编译运行是没有问题的。
1010 | Accepted | 192K | 32MS |
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 100;
int n = 0;
int stamps[N];
struct Allocation{
int nstamps;
int ntypes;
int highestvalue;
bool tie;
vector<int> stamps;
Allocation()
{
nstamps = 0;
ntypes = 0;
highestvalue = 0;
tie = false;
stamps.resize(4);
}
};
vector<Allocation> sols;
void updateSolution(const int req, Allocation &allocation, int *type, int cnt)
{
if(sols[req].ntypes < allocation.ntypes ||
sols[req].ntypes == allocation.ntypes
&& sols[req].nstamps > allocation.nstamps ||
sols[req].ntypes == allocation.ntypes
&& sols[req].nstamps == allocation.nstamps
&& sols[req].highestvalue < allocation.highestvalue)
{
sols[req] = allocation;
sols[req].tie = false;
}
else if(sols[req].ntypes == allocation.ntypes
&& sols[req].nstamps == allocation.nstamps
&& sols[req].highestvalue == allocation.highestvalue)
{
sols[req].tie = true;
}
}
void updateAllocation(int &req, Allocation &allocation, int *type, int cnt)
{
allocation.nstamps = cnt;
allocation.stamps[cnt - 1] = stamps[type[cnt - 1]];
if(type[cnt - 1] != type[cnt - 2])
{
allocation.ntypes++;
}
allocation.highestvalue = stamps[type[cnt - 1]];
}
int main()
{
int stamp;
while(fscanf(stdin, "%d", &stamp) > 0)
{
memset(stamps, 0, n * sizeof(int));
n = 0;
int pre = 0;
int cnt = 0;
while(stamp != 0)
{
if(stamp == pre)
{
cnt++;
}
else
{
cnt = 0;
}
if(cnt < 5)
{
stamps[n] = stamp;
n++;
}
fscanf(stdin, "%d", &stamp);
}
//sort(stamps, stamps + n);
vector<int> reqs;
int reqest, maxreq = 0;
fscanf(stdin, "%d", &reqest);
while(reqest != 0)
{
reqs.push_back(reqest);
if(reqest > maxreq)
{
maxreq = reqest;
}
fscanf(stdin, "%d", &reqest);
}
int upperbnd = min(stamps[n - 1] * 4, maxreq);
if(!sols.empty())
{
sols.clear();
}
sols.resize(upperbnd + 1);
int type[4], req[4];
Allocation allocation[4];
for(type[0] = 0; type[0] < n; ++type[0])
{
req[0] = stamps[type[0]];
if(req[0] > upperbnd)
{
break;
}
allocation[0] = Allocation();
allocation[0].nstamps = 1;
allocation[0].stamps[0] = stamps[type[0]];
allocation[0].ntypes = 1;
allocation[0].highestvalue = stamps[type[0]];
updateSolution(req[0], allocation[0], type, 1);
for(type[1] = type[0]; type[1] < n; ++type[1])
{
req[1] = req[0];
req[1] += stamps[type[1]];
if(req[1] > upperbnd)
{
break;
}
allocation[1] = allocation[0];
updateAllocation(req[1], allocation[1], type, 2);
updateSolution(req[1], allocation[1], type, 2);
for(type[2] = type[1]; type[2] < n; ++type[2])
{
req[2] = req[1];
req[2] += stamps[type[2]];
if(req[2] > upperbnd)
{
break;
}
allocation[2] = allocation[1];
updateAllocation(req[2], allocation[2], type, 3);
updateSolution(req[2], allocation[2], type, 3);
for(type[3] = type[2]; type[3] < n; ++type[3])
{
req[3] = req[2];
req[3] += stamps[type[3]];
if(req[3] > upperbnd)
{
break;
}
allocation[3] = allocation[2];
updateAllocation(req[3], allocation[3], type, 4);
updateSolution(req[3], allocation[3], type, 4);
}
}
}
}
for(int i = 0; i < reqs.size(); ++i)
{
int req = reqs[i];
fprintf(stdout, "%d ", req);
if(req > upperbnd || sols[req].ntypes == 0)
{
fprintf(stdout, "---- none\n");
}
else
{
fprintf(stdout, "(%d):", sols[req].ntypes);
if(sols[req].tie)
{
fprintf(stdout, " tie\n");
}
else
{
for(int j = 0; j < sols[req].nstamps; ++j)
{
fprintf(stdout, " %d", sols[req].stamps[j]);
}
fprintf(stdout, "\n");
}
}
}
}
return 0;
}