P3052 [USACO12MAR]Cows in a Skyscraper G

看到这个数据范围,显然状压
用\(f[i][j]\)表示开了i个电梯,装的牛的集合为j,每次往最后一台电梯加入牛,让最后一台电梯的重量为\(f[i][j]\)

std::mt19937 r(std::chrono::system_clock::now().time_since_epoch().count());
const int N = 21;
int n, W, w[N];

namespace DP {
	int f[19][1 << 19], mx; //¿ªÁËi¸öµçÌÝ£¬Ñ¡ÁËj¼¯ºÏÀïÃæµÄÅ££¬ÖØÁ¿Îªfij

	int main() {
		memset(f, 0x3f, sizeof f);
		mx = (1 << n) - 1;

		rep(i, 1, n) {
			f[1][1 << (i - 1)] = w[i];
		}

		rep(i, 1, n) { //µçÌÝÊý
			rep(j, 0, mx) {
				if(f[i][j] > 1e9) continue;
				rep(k, 1, n) {
					if(j & (1 << (k - 1))) continue;
					if(f[i][j] + w[k] <= W) {
						f[i][j | 1 << (k - 1)] = min(f[i][j | 1 << (k - 1)], f[i][j] + w[k]);
					} else {
						f[i + 1][j | 1 << (k - 1)] = min(f[i][j | 1 << (k - 1)], w[k]);
					}
				}
			}
		}
		rep(i, 1, n) {
			if(f[i][mx] < 1e9) {
				out(i, '\n');
				break;
			}
		}

		return 0;
	}

}

namespace rnd {
	int main() {
		int t = clock();
		int ans(n);
		
		while(clock() - t < CLOCKS_PER_SEC * 0.98)
		{
			srand(r());
			int g(0), num(1);
			rep(i, 1, n) {
				if(g + w[i] <= W) {
					g += w[i];
				} else {
					g = w[i];
					++num;
				}
			}
			ans = min(ans, num);
			std::random_shuffle(w + 1, w + n + 1);
		}
		out(ans, '\n');
		return 0;
	}
}
上一篇:包机制


下一篇:2021-08-03