Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 22779 | Accepted: 7894 |
Description
Input
Output
Sample Input
3 4 1 1 1 1 5 10 20 30 40 50 8 1 7 2 6 4 4 3 5
Sample Output
yes no yes
能做,就是。。。。
看大神排序剪枝优化以后才过了,排序以后对于组边的时候过大的边可以舍去不用了,减少了很多不必要的搜索
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; int M, a[100], tem, sum; bool vis[100], flag; void dfs(int n, int pos, int cou) { if (n != 0) { //没有组成一边 //注意flag,如果已经组成正方形就没必要继续了 for (int i = pos; !flag && i < M && a[i] <= n; i++) { if (!vis[i]) { vis[i] = true; dfs(n - a[i], i + 1, cou); //继续往大搜索 vis[i] = false; } } } else { //组成一边 if (cou == 4) { flag = true; } else { dfs(tem, 0, cou + 1); } } } int main() { int N; scanf("%d", &N); while(N--) { memset(vis, false, sizeof(vis)); scanf("%d", &M); sum = 0; int maxn = -1; for (int i = 0; i < M; i++) { scanf("%d", &a[i]); sum += a[i]; maxn = max(a[i], maxn); } if (sum % 4 != 0) { puts("no"); continue; } tem = sum / 4; //如果最大的边比正方形的边大 //一定组不成 if (maxn > tem) { puts("no"); continue; } //对边排好序,在DFS的时候 sort(a, a + M); flag = false; dfs(tem, 0, 1); //分别找4条边 if (flag) { puts("yes"); } else { puts("no"); } } return 0; }
另一种等价写法,但是递归边界有所不同,递归一定要看清楚入口处的状态是什么,是完成了还是待完成的,每个变量对应的状态的准确含义是什么一定要
搞清楚
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; int N, s[30], tem; bool vis[30]; bool dfs(int pos, int ans, int cou) { ///注意dfs状态,dfs(pos, ans, cou) ///其中cou表示“已完成”cou个,ans是组边时“已完成”的和,pos是“待计算”的位置 if (cou == 4) return true; if (ans != tem) { for (int i = pos; i < N && ans + s[i] <= tem; i++) { if (!vis[i]) { vis[i] = true; if (dfs(i + 1, ans + s[i], cou)) { return true; } vis[i] = false; } } } else { //if (cou == 4) return true; if (dfs(0, 0, cou + 1)) return true; } return false; } int main() { int T; scanf("%d", &T); while (T--) { scanf("%d", &N); int sum = 0; for (int i = 0; i < N; i++) { scanf("%d", &s[i]); sum += s[i]; } if (sum % 4 != 0) { puts("no"); continue; } tem = sum / 4; sort(s, s + N); memset(vis, false, sizeof(vis)); if (dfs(0, 0, 0)) { puts("yes"); } else { puts("no"); } } return 0; }