版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/QingCoffe/article/details/85222638
Time Limit Exceeded
直接暴搜.....死的很安详
没办法...第一个想法就是这个:
# include<iostream>
# include<algorithm>
//# include<Windows.h>
using namespace std;
int n[6] = { 0 };
int ans, total, flag;
int Visit[6];
void OUT(bool b) {
static int index = 0;
if (index)cout << endl;
cout << "Collection #" << ++index << ":" << endl;
if (b) {
cout << "Can be divided." << endl;
}
else {
cout << "Can't be divided." << endl;
}
}
int INput(void) {
int total_ = 0;
for (int i = 0; i < 6; i++) {
cin >> n[i];//录入弹珠信息
Visit[i] = n[i];
total_ += (i+1)*n[i];
}
return total_;
}
void Fen(int index) {//index 层数一共6层,i第几个物品 n[i]为该层有的物品数
for (int i = index; i < 6 && !flag; i++) {
if (!index) {//0 层 ans =0;初始化访问表
ans = 0;
for (int j = 0; j < 6; j++) {
Visit[j] = n[j];
} //初始化访问表
}
if (!Visit[i])continue;
for (int k = 0; k <= n[i]; k++) {//首先不拿---直到拿n[i]个
Visit[i] -= k;//先拿K个
ans += (i + 1)*k; //得到K个总价值
if (ans < (total / 2)) {//价值小于目标数
Fen(i + 1);//递归到下一层
ans -= (i + 1)*k; //拿回的东西放回去
Visit[i] += k;
}
else if (ans == total / 2) {
flag = true; return;//找到并返回
}
else {//价格已经超出了 剪枝
ans -= (i + 1)*k; //东西放回去 结束
Visit[i] += k;
return;
}
}
}
}
int main()
{
total = INput();//拿到第一个输入的价值
while (!((*max_element(n, n + 6)) == 0)) {//全0不做
if (total & 1)OUT(false);//总价值为奇数不可分割
else {//尝试分割
flag = false;//未找到
Fen(0);//从0开始找
if (flag)OUT(true);
else OUT(false);
}
total = INput();//录入下一次信息
}
system("pause");
return 0;
}
因为超时所以不知道准确答案,因此我写了个检测......用的别人正确的AC码做参考:随机生成了10W个数据显示是对的
# include<iostream>
# include<algorithm>
#include <cstdio>
#include <cstring>
//# include<Windows.h>
using namespace std;
int n[6] = { 0 };
int a[6];
int ans, total, flag;
int Visit[6];
const int SIZE = 120000 + 16;
int dp[SIZE];
void Fen(int index) {//index 层数一共6层,i第几个物品
for (int i = index; i < 6 && !flag; i++) {
if (!index) {//0 层 ans =0;初始化访问表
ans = 0;
for (int j = 0; j < 6; j++) {
Visit[j] = n[j];
} //初始化访问表
}
if (!Visit[i])continue;
for (int k = 0; k <= n[i]; k++) {//首先不拿---直到拿n[i]个
Visit[i] -= k;//先拿K个
ans += (i + 1)*k; //得到K个总价值
if (ans < (total / 2)) {//价值小于目标数
Fen(i + 1);//递归到下一层
ans -= (i + 1)*k; //拿回的东西放回去
Visit[i] += k;
}
else if (ans == total / 2) {
flag = true; return;//找到并返回
}
else {//价格已经超出了 剪枝
ans -= (i + 1)*k; //东西放回去 结束
Visit[i] += k;
return;
}
}
}
}
void RAND(void) {
total = 0;
for (int i = 0; i < 6; i++) {
n[i] = rand() % 5 + 1;
a[i] = n[i];
Visit[i] = n[i];
total += (i + 1)*n[i];
}
}
bool My(void) {
if (total & 1)return false;//总价值为奇数不可分割
else {//尝试分割
flag = false;//未找到
Fen(0);//从0开始找
if (flag)return true;
else return false;
}
}
bool check()
{
for (int i = 0; i<6; i++)
if (a[i] != 0)
return true;
return false;
}
bool YO(void) {
int sum;
int t = 0;
while (true)
{
sum = 0;
for (int i = 0; i<6; i++)
{
sum += (i + 1)*a[i];
}
if (!check())
break;
if (sum % 2 == 1)
{
return false;
}
else
{
memset(dp, -1, sizeof(dp));
int k = sum / 2;
dp[0] = 0;
for (int i = 0; i<6; i++)
{
for (int j = 0; j <= k; j++)
{
if (dp[j] >= 0)
{
dp[j] = a[i];
}
else if (j<(i + 1) || dp[j - (i + 1)] <= 0)
{
dp[j] = -1;
}
else
{
dp[j] = dp[j - (i + 1)] - 1;
}
}
}
if (dp[k] >= 0)
{
return true;
}
else
{
return false;
}
}
}
}
int main()
{
bool re1, re2;
int index = 0;
while((index+1)<10000){
cout << ++index << endl;
RAND();
re1 = My();
re2 = YO();
if (re1 != re2) {
cout << "出现不同结果:" << endl;
cout << "--------------------" << endl;
cout << "MY:" << re1 << endl;
cout << "--------------------" << endl;
cout << "--------------------" << endl;
cout << "YO:" << re2 << endl;
cout << "--------------------" << endl;
cout << "--------------------" << endl;
cout << "n 的情况: " << endl;
for (int i = 0; i<6; i++)
{
cout <<i+1<<" : "<< a[i] << " "<<n[i]<<endl;
}
cout << "--------------------" << endl;
getchar();
}
}
system("pause");
return 0;
}