【cf 487C】【数论+构造】【根据前缀积取模构造序列】
传送门:
http://swjtuoj.handsomehow.com/problem/28/
思路:
暴搜+剪枝即可
通过下列裁剪会加快运算速度
1.将狗粮总数/4,不能整除直接输出no
2.如果有比平均数大的,直接输出no
3.dfs时如果前3个满足,则最后一个一定满足
ps:搜索,dp,数学这些基础内容要加大力度练!!!
代码:
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define ff first
#define ss second
#define pb push_back
#define ll long long
#define mod 1000000007
#define ull unsigned long long
#define mst(ss,b) memset(ss,b,sizeof(ss));
#define pl(x) cout << #x << "= " << x << endl;
const int inf = 0x3f3f3f3f;
const int N = 1e5+5;
int n, a[25], ave;
bool vis[25];
bool dfs(int id, int sum, int div){
if(sum == ave){
id = sum = 0;
div++;
if(div == 3)return 1;
}
for(int i=id; i<=n; i++){
if(!vis[i]){
if(sum+a[i] <= ave){
vis[i] = 1;
if(dfs(i+1, sum+a[i], div))return 1;
vis[i] = 0;
}
}
}
return 0;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
mst(vis, 0);
scanf("%d", &n);
int mx = 0, sum = 0;
for(int i=1; i<=n; i++)scanf("%d", &a[i]), sum += a[i], mx = max(mx, a[i]);
ave = sum/4;
if(sum % 4 || mx>ave)puts("no");
else{
if(dfs(1, 0, 0))puts("yes");
else puts("no");
}
}
return 0;
}
描述:
分狗粮
发布时间: 2017年3月18日 17:14 最后更新: 2017年3月18日 17:17 时间限制: 2000ms 内存限制: 128M
描述
今天handsomehow给大家发了n包狗粮,每一包狗粮里面装有a颗狗粮.而现在你需要把这n包狗粮平均分成4份,以便你和你的室友享用,并且不能把包装给拆开.问你是否能够平均分给你的室友,并且没有剩余?
输入
第一行是一个整数T,表示数据组数.
接下来有T组数据.
每组数据的开头是一个整数n(4<=n<=20),表示有n包狗粮,接着n个数代表每包狗粮的颗数.
保证每包狗粮的颗数a满足条件1<=a<=10,000
输出
如果能够均分一行输出yes
否则输出一行no
样例输入1 复制
2
6 1 1 1 1 1 3
9 1 7 2 2 6 3 5 4 2
样例输出1
no
yes
提示
对于第二组数据,你可以这样分(1,7),(2,6),(3,5),(2,4,2),刚好每人8颗.
对于第一组数据,你不能将他们平均分成4堆.(将会有剩余)