题目描述
http://poj.org/problem?id=1014
思路
1.石子总价值为奇数肯定无法划分
2.石子总价值为偶数,则划分目标为总价值一半
3.石子总数去除掉价值为0的
4.采用DFS暴搜,状态量为目标价值和石子总数
5.结束条件为目标价值为0且石子总数为0
6.只能分成两组
实测已经AC
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef unsigned int UINT32;
typedef unsigned short UINT16;
typedef unsigned char UINT8;
typedef int INT32;
typedef short INT16;
typedef char INT8;
typedef void VOID;
#define TRUE (1)
#define FALSE (0)
#define SUCCESS (0)
#define FAIL (1)
#define MAX_MARBLE_NUM (20005)
#define MAX_INPUT_NUM (6)
UINT32 g_inputNum[MAX_INPUT_NUM];/*输入数组*/
UINT32 g_inputIndex = 0;/*输入数组下标索引*/
UINT32 g_dividValue;/*划分价值*/
UINT32 g_value[MAX_MARBLE_NUM];/*记录输入价值数组*/
UINT32 g_valueIndex = 0;
UINT32 g_visit[MAX_MARBLE_NUM];/*记录是否访问过*/
UINT32 g_dividFlag = FALSE;/*是否能够划分*/
UINT32 g_loop = 1;/*输入组数*/
INT32 cmpfunc(const VOID * a, const VOID * b)
{
return (*(INT32*)b - *(INT32*)a);/* 由大到小 */
}
VOID DFS(UINT32 leftValue, UINT32 leftMarbleNum)
{
UINT32 i;
if (leftValue == 0) {
g_dividFlag = TRUE;
return;
}
if (g_dividFlag == TRUE) {
/*剪枝*/
return;
}
if ((leftValue > 0) && (leftMarbleNum > 0)) {
for (i = 0; i < g_valueIndex; i++) {
if ((g_visit[i] == FALSE) && (leftValue >= g_value[i])) {
g_visit[i] = TRUE;
leftValue -= g_value[i];
leftMarbleNum -= 1;
DFS(leftValue, leftMarbleNum);
leftValue += g_value[i];
leftMarbleNum += 1;
}
}
}
return;
}
UINT32 IsBreak()
{
UINT32 i;
for (i = 0; i < MAX_INPUT_NUM; i++) {
if (g_inputNum[i] != 0) {
return FALSE;
}
}
return TRUE;
}
int main()
{
INT32 i, j;
UINT32 inputNum;
UINT32 totalValue;
UINT32 totalNum;
while (scanf_s("%d", &inputNum) != EOF) {
g_inputNum[g_inputIndex] = inputNum;
g_inputIndex++;
if (g_inputIndex == MAX_INPUT_NUM) {
if (IsBreak() == TRUE) {
break;
}
g_inputIndex = 0;/*数组下标归0*/
printf("Collection #%d:\n", g_loop);
g_loop++;/*输入数据组数+1*/
/* 计算总价值和总个数,总价值为奇数,肯定无法均分为两部分 */
totalNum = 0;
totalValue = 0;
g_valueIndex = 0;
for (i = MAX_INPUT_NUM - 1; i >= 0; i--) {
if (g_inputNum[i] == 0) {
continue;
}
totalNum += g_inputNum[i];
totalValue += (g_inputNum[i] * (i + 1));
for (j = 0; j < g_inputNum[i]; j++) {
g_value[g_valueIndex] = (i + 1);
g_visit[g_valueIndex] = FALSE;
g_valueIndex++;
}
}
if (totalValue % 2 != 0) {
printf("Can't be divided.\n");
printf("\n");
continue;
}
g_dividValue = totalValue / 2;/*划分价值为总价值一半*/
for (i = 0; i < g_valueIndex; i++) {
if (g_value[i] > g_dividValue) {
printf("Can't be divided.\n");
printf("\n");
break;
}
}
g_dividFlag = FALSE;
DFS(g_dividValue, totalNum);
if (g_dividFlag == TRUE) {
printf("Can be divided.\n");
printf("\n");
}
else {
printf("Can't be divided.\n");
printf("\n");
}
}
}
return 0;
}