hdu 5355 Cake(回溯)

来源:互联网 发布:药店软件哪个好 编辑:程序博客网 时间:2024/06/03 17:44

题目链接:hdu 5355 Cake


每次扣掉2m,直到n小于40,再用回溯暴力出方案。


#pragma comment(linker, "/STACK:102400000,102400000")#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 50;typedef long long ll;int s[maxn], t[maxn];vector<int> G[maxn];bool dfs (int d, int k, int n, int m) {if (d <= 0)return true;for (int i = 1; i <= m; i++) {if (s[i] + d > k)continue;t[d] = i;s[i] += d;if (dfs(d-1, k, n, m))return true;t[d] = 0;s[i] -= d;}return false;}void solve (int n, int m) {for (int i = 1; i <= m; i++) {s[i] = t[i] = 0;G[i].clear();}while (n > 40) {for (int i = 1; i <= m; i++)G[i].push_back(n--);for (int i = m; i; i--)G[i].push_back(n--);}dfs(n, n * (n+1) / 2 / m, n, m);for (int i = 1; i <= n; i++)G[t[i]].push_back(i);}int main () {int cas, n, m;scanf("%d", &cas);while (cas--) {scanf("%d%d", &n, &m);ll k = 1LL * n * (n + 1) / 2;if (k % m == 0 && n >= 2 * m - 1) {printf("YES\n");solve(n, m);for (int i = 1; i <= m; i++) {sort(G[i].begin(), G[i].end());int t = G[i].size();printf("%d", t);for (int j = 0; j < t; j++)printf(" %d", G[i][j]);printf("\n");}} else {printf("NO\n");}}return 0;}


0 0
原创粉丝点击