这道题我是用一个数组记录每个 q (1~Q)的最好组成(之后看标准答案,这里的空间复杂度可以降低的,即记录“前一个"是谁和最后增加的那个,可以回溯回去)。然后类似dijkstra(基本就是Dijkstra),从当前最好的组成向外扩展。扩展的时候从当前组成的下一个没用的pail开始,每个pail都增加到Q为止。这些q都放在一个priority_queue里面。 如果出队的是Q,那么任务就完成了。
注:C++ STL中priority_queue的第三个参数,即比较函数,应该是如果第一个比第二个大,就返回true.似乎也不存在自己和自己比较的情况(和sort的第三个参数感觉不一样)。
Executing... Test 1: TEST OK [0.005 secs, 3504 KB] Test 2: TEST OK [0.005 secs, 3504 KB] Test 3: TEST OK [0.003 secs, 3504 KB] Test 4: TEST OK [0.005 secs, 3504 KB] Test 5: TEST OK [0.003 secs, 3504 KB] Test 6: TEST OK [0.046 secs, 3768 KB] Test 7: TEST OK [0.065 secs, 3504 KB] Test 8: TEST OK [0.459 secs, 3768 KB] Test 9: TEST OK [0.132 secs, 3768 KB] Test 10: TEST OK [0.594 secs, 3768 KB] All tests OK.
/*
ID: thestor1
LANG: C++
TASK: milk4
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <climits>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
vector<vector<int> > combinations(20000 + 1, vector<int>());
class cmpbycombinations
{
public:
bool operator() (const int& lhs, const int&rhs) const
{
// cout<<"[debug]"<<lhs<<" vs "<<rhs<<":";
if (combinations[lhs].size() < combinations[rhs].size())
{
// cout<<"false"<<endl;
return false;
}
else if (combinations[lhs].size() == combinations[rhs].size())
{
for (int i = 0; i < combinations[lhs].size(); ++i)
{
if (combinations[lhs][i] < combinations[rhs][i])
{
// cout<<"false"<<endl;
return false;
}
else if (combinations[lhs][i] > combinations[rhs][i])
{
// cout<<"true"<<endl;
return true;
}
}
}
else
{
// cout<<"true"<<endl;
return true;
}
if (lhs < rhs)
{
// cout<<"false"<<endl;
return false;
}
else
{
// cout<<"true"<<endl;
return true;
}
}
};
bool smaller(std::vector<int> &newcomb, std::vector<int> comb)
{
if (newcomb.size() < comb.size())
{
return true;
}
else if (newcomb.size() > comb.size())
{
return false;
}
else
{
for (int i = 0; i < newcomb.size(); ++i)
{
if (newcomb[i] < comb[i])
{
return true;
}
else if (newcomb[i] > comb[i])
{
return false;
}
}
return false;
}
}
int main()
{
ifstream fin("milk4.in");
ofstream fout("milk4.out");
int Q;
fin>>Q;
int P;
fin>>P;
vector<int> pails(P);
for (int i = 0; i < P; ++i)
{
fin>>pails[i];
}
sort(pails.begin(), pails.end());
priority_queue<int, vector<int>, cmpbycombinations> que;
for (int i = 0; i < pails.size(); ++i)
{
for (int j = 1; j <= Q; ++j)
{
if (combinations[j].size() == 0 && j % pails[i] == 0)
{
combinations[j].push_back(i);
que.push(j);
// cout<<"[debug]"<<j<<" push"<<endl;
// for (int k = 0; k < combinations[j].size(); ++k)
// {
// cout<<pails[combinations[j][k]]<<"\t";
// }
// cout<<endl;
}
}
// if (combinations[pails[i]].size() == 0)
// {
// combinations[pails[i]].push_back(i);
// que.push(pails[i]);
// cout<<"[debug]"<<pails[i]<<" push"<<endl;
// for (int k = 0; k < combinations[pails[i]].size(); ++k)
// {
// cout<<pails[combinations[pails[i]][k]]<<"\t";
// }
// cout<<endl;
// }
}
while (!que.empty())
{
int q = que.top();
// cout<<"[debug]"<<q<<" pop"<<endl;
// for (int k = 0; k < combinations[q].size(); ++k)
// {
// cout<<pails[combinations[q][k]]<<"\t";
// }
// cout<<endl;
que.pop();
if (q == Q)
{
break;
}
assert(combinations[q].size() != 0);
int last = combinations[q][combinations[q].size() - 1];
// if (combinations[q].size() == 1 && pails[last] == 1025)
// {
// cout<<"[debug]"<<endl;
// }
int next = last + 1;
while (next < pails.size())
{
std::vector<int> newcomb = combinations[q];
newcomb.push_back(next);
int nq = q + pails[next];
while (nq <= Q)
{
if (combinations[nq].size() == 0 || smaller(newcomb, combinations[nq]))
{
// combinations[nq] = combinations[q];
// // if (next != last)
// // {
// combinations[nq].push_back(next);
combinations[nq] = newcomb;
// }
// cout<<"[debug]"<<nq<<" push"<<endl;
// for (int k = 0; k < combinations[nq].size(); ++k)
// {
// cout<<pails[combinations[nq][k]]<<"\t";
// }
// cout<<endl;
que.push(nq);
}
nq += pails[next];
}
next++;
}
}
assert(combinations[Q].size() != 0);
fout<<combinations[Q].size();
for (int i = 0; i < combinations[Q].size(); ++i)
{
fout<<" "<<pails[combinations[Q][i]];
}
fout<<endl;
fin.close();
fout.close();
return 0;
}