#include <stdio.h>
#include <stdbool.h> 
#define CAPACITY 30 
#define N 3     
#define QUEUE_SIZE 100 // 定义队列的最大容量（静态分配）  
typedef struct {// 定义节点结构体 
    int level;   // 当前节点所在的层数（即考虑第几个物品）
    int weight;  // 当前已装入物品的总重量
    int value;   // 当前已获得的总价值
    bool items[N]; // 布尔数组，记录每个物品是否被选择
} Node; 
// 定义队列结构体，使用数组模拟队列
typedef struct {
    Node liveList[QUEUE_SIZE];  // 队列的存储数组
    int front, rear;            // 队列的头部和尾部指针
} Queue; 
// 初始化队列，设置front为0，rear为-1表示空队列
void initQueue(Queue* queue) {
    queue->front = 0; queue->rear = -1; 
} 
// 检查队列是否为空，如果front大于rear则为空
int isEmpty(Queue* queue) {
    return queue->front > queue->rear;
} 
// 向队列中添加元素，使用前置自增保证新元素放置在正确位置
void insertQueue(Queue* queue, Node item) {
    queue->liveList[++(queue->rear)] = item;
} 
// 从队列中移除并返回元素，如果队列为空则返回一个空节点
Node popQueue(Queue* queue) {
    if (isEmpty(queue)) { 
        static Node emptyNode = {-1, -1, -1, {false}};
        return emptyNode;
    }
    return queue->liveList[(queue->front)++];
} 
// 使用广度优先搜索（BFS）解决01背包问题
void bag01bfs(Queue* queue, int weightArr[], int value[], int n, int maxWeight,
                                              int* maxValue, bool bestItems[]) {
    // 创建初始节点（level=0，weight=0，value=0，items全为false），并将其加入队列
    Node node = {0, 0, 0, {false}};
    insertQueue(queue, node);  
    while (!isEmpty(queue)) { // 开始广度优先搜索
        Node u = popQueue(queue); // 取出队列中的第一个节点 
        // 如果遇到空节点，跳过本次循环
        if (u.level == -1) continue;  
        if (u.level == n) { // 如果到达最后一层（所有物品都考虑完毕） 
            if (u.value > *maxValue) { // 更新最大价值和最优解
                *maxValue = u.value;
                for (int i = 0; i < N; ++i)
                    bestItems[i] = u.items[i];
            }
            continue;
        } 
        // 分支：包含当前物品的情况
        if (u.weight + weightArr[u.level] <= maxWeight) {
            // 创建新节点v，代表选择了当前物品的情况
            Node v = {u.level + 1, u.weight + weightArr[u.level], u.value + value[u.level]};
            for (int i = 0; i < N; ++i)
                v.items[i] = u.items[i];
            v.items[u.level] = true;
            insertQueue(queue, v);
        } 
        // 分支：不包含当前物品的情况
        Node w = {u.level + 1, u.weight, u.value};
        for (int i = 0; i < N; ++i)
            w.items[i] = u.items[i];
        insertQueue(queue, w);
    }
}

int main() {
    // 定义每个物品的重量和价值
    int weightArr[N] = {16, 15, 15}; // 每个物品的重量
    int value[N] = {45, 25, 25};     // 每个物品的价值  
    int maxValue = 0; // 最大价值
    bool bestItems[N] = {false}; // 记录最优解的物品选择情况  
    Queue queue;
    initQueue(&queue); // 初始化队列 
    // 调用bag01bfs函数解决背包问题
    bag01bfs(&queue, weightArr, value, N, CAPACITY, &maxValue, bestItems); 
    // 输出结果
    printf("最大价值是 %d\n", maxValue);
    printf("选择的物品：");
    for (int i = 0; i < N; ++i) {
        if (bestItems[i])
            printf("%d ", i + 1); // 输出物品编号（从1开始）
    } 
    return 0;
}