【发布时间】:2012-12-28 16:17:50
【问题描述】:
我一直在 ACM 提交解决此问题的程序。 Problem ID=1922 但我的解决方案在测试 3 中不断超过时间限制。
我的想法是使用蛮力但有一些分支切断。以下是我的 Java 代码,如果有更快的解决方案或改进,将不胜感激……我想这根本不难,因为难度只有 195,但我就是无法接受。
终于被接受了。该算法首先对英雄进行排序,并从最小的愿望开始。只需 O(n)..
我的 Java 代码是迄今为止最快的Solution Rank
非常感谢!
public class testtest
{
static boolean[] used;
// length of heros
static int ulen;
// list of heros
static Wish[] w;
// number of possible teams
static int count = 0;
// and output
static StringBuilder str = new StringBuilder();
// add the team
// check if it is a valid team
static boolean check(int len)
{
for (int i = 0; i < ulen; i ++)
{
if (!used[i])
{
// adding another hero makes it reliable, so invalid
if (w[i].wish <= len + 1)
{
return false;
}
}
}
return true;
}
// search the teams, team size = total, current pick = len, start from root + 1
static void search(int root, int total, int len)
{
if (len >= total) // finish picking len heros
{
if (check(total)) // valid
{
print(total); // add to output
}
return;
}
for (int i = root + 1; i < ulen; i ++)
{
if (w[i].wish > len + ulen - i)
{
return; // no enough heros left, so return
}
else
if (w[i].wish <= total) // valid hero for this team
{
used[i] = true;
search(i, total, len + 1); // search next hero
used[i] = false;
}
}
}
public static void main(String[] args) throws IOException
{
BufferedReader rr = new BufferedReader(new InputStreamReader(System.in));
ulen = Integer.parseInt(rr.readLine());
w = new Wish[ulen];
for (int i = 0; i < ulen; i ++)
{
w[i] = new Wish(i + 1, Integer.parseInt(rr.readLine()));
}
Arrays.sort(w);
used = new boolean[ulen];
Arrays.fill(used, false);
for (int i = 1; i <= ulen; i ++)
{
for (int j = 0; j <= ulen - i; j ++)
{
if (w[j].wish <= i) // this hero is valid
{
used[j] = true;
search(j, i, 1);
used[j] = false;
}
}
}
System.out.println(count);
System.out.print(str);
}
}
【问题讨论】:
-
你可能想看看组合数学。
-
我认为算法仍然基于搜索,因为需要打印整个列表,而不仅仅是答案总数。
-
与算法无关,但在
StringBuffer.append调用中更改+肯定会减少一些时间。 -
@ChristopherSchultz 不过我认为效果不会很大。
-
您的代码运行需要多长时间?