这里有题解:http://blog.sina.com.cn/s/blog_8442ec3b01017ks5.html
请看神剪枝
二分能够得到多少木板,然后用Dfs验证能否全部得到1..mid这些木块。
这样会有1个点过不了。
这道题加一个优化:如果当前这个木块和前一个木块相同(倒着枚举小木块),那么搜大木块的时候就从当前这个大木块开始,具体看代码。
由于这是USACO题目的弱化版,如果是USACO的话,还有一个优化才能过:用waste表示每一个已经裁过的木材浪费的木材和,所谓浪费的木材就是最小的木块都比它大,那么他当前就已经裁不出任何木块了。就把这个木材加到waste去,如果waste>木材和-s[mid],说明这样裁木材是错误的,所以减枝。
const int N = 20;
int Dat[N], Base[N], Sum;
int n, m;
inline void Input() {
scanf("%d%d", &n, &m);
Sum = 1;
Rep(i, n) Sum *= m, Base[i] = 1;
}
inline void Write() {
Sum--;
Rep(i, n) printf("%c", Dat[i] < 10 ? '0' + Dat[i] : 'A' + Dat[i] - 10);
printf("\n");
}
inline void Solve() {
Write();
while(Sum) {
Rep(i, n)
if(Dat[i] + Base[i] > -1 && Dat[i] + Base[i] < m) {
Dat[i] += Base[i];
break;
} else Base[i] *= -1;
Write();
}
}
int main() {
#ifndef ONLINE_JUDGE
SETIO("1081");
#endif
Input();
Solve();
return 0;
}