【 OJ 】 HDOJ1059 18年12月23日14:37 [ 51 ]

版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}

猜你喜欢

转载自blog.csdn.net/QingCoffe/article/details/85222638