首页 > 试题广场 >

术式终端的并行调度

[编程题]术式终端的并行调度
  • 热度指数:1046 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 512M,其他语言1024M
  • 算法知识视频讲解
小红正在术士协会的实训室里调试一套魔导调度系统。这套系统由若干台规格相同的核心服务器组成,每台服务器都拥有固定的 CPU 算力上限 latex 和内存容量上限 latex
小红手头共有 latex 个待运行的术式任务。对于第 latex 个任务,它需要消耗 latex 单位的算力、消耗 latex 单位的内存,并在运行成功后产生 latex 单位的术式价值。对于每一台独立的服务器,在其上运行的任务集合 latex 必须严格满足以下约束:
1. 任务的算力消耗总和不得超过服务器上限,即 latex
2. 任务的内存消耗总和不得超过服务器上限,即 latex
现在,小红希望分别计算:当她拥有 latex 台服务器时,通过合理分配任务到各台服务器上,所能获得的任务总价值最大分别是多少?

输入描述:
输入仅包含一组测试数据。
第一行包含三个整数 latex (latex),分别代表任务的总数、单台服务器的 CPU 算力上限以及内存容量上限。
接下来 latex 行,每行包含三个整数 latex (latex),分别表示第 latex 个术式任务的算力需求、内存需求及产生的价值。


输出描述:
输出共 latex 行。
latex 行(latex)输出一个整数,表示在使用 latex 台服务器的情况下,所能获得的最大任务总价值。
示例1

输入

3 3 10
1 4 1
2 5 2
2 6 4

输出

5
7
7

说明

当拥有 latex 台服务器时:小红可以选择运行第 1 个和第 3 个任务。总算力消耗为 latex,总内存消耗为 latex,此时获得最大价值 latex
当拥有 latex 台服务器时:第一台服务器运行任务 1 和 3,第二台服务器运行任务 2。总价值为 latex
当拥有 latex 台服务器时:由于 2 台服务器已经可以运行全部任务,第 3 台服务器会保持空闲,最大价值仍为 7。
#include <bits/stdc++.h>
using namespace std;

int n, C, M;
int c[20], m[20], v[20];

int sumC[1<<15], sumM[1<<15], sumV[1<<15];
bool ok[1<<15];

int dp[1<<15][16]; // mask + 服务器数量

int main() {
    cin >> n >> C >> M;
    for (int i = 0; i < n; i++) {
        cin >> c[i] >> m[i] >> v[i];
    }

    int N = 1 << n;

    // 预处理每个子集
    for (int mask = 0; mask < N; mask++) {
        for (int i = 0; i < n; i++) {
            if (mask & (1 << i)) {
                sumC[mask] += c[i];
                sumM[mask] += m[i];
                sumV[mask] += v[i];
            }
        }
        if (sumC[mask] <= C && sumM[mask] <= M) {
            ok[mask] = true;
        }
    }

    // 初始化
    for (int i = 0; i < N; i++)
        for (int k = 0; k <= n; k++)
            dp[i][k] = 0;

    // DP
    for (int k = 1; k <= n; k++) {
        for (int mask = 0; mask < N; mask++) {
            for (int sub = mask; sub; sub = (sub - 1) & mask) {
                if (ok[sub]) {
                    dp[mask][k] = max(dp[mask][k],
                        dp[mask ^ sub][k - 1] + sumV[sub]);
                }
            }
        }
    }

    // 输出答案
    for (int k = 1; k <= n; k++) {
        int ans = 0;
        for (int mask = 0; mask < N; mask++) {
            ans = max(ans, dp[mask][k]);
        }
        cout << ans << endl;
    }

    return 0;
}
发表于 2026-04-13 14:48:27 回复(0)
状态压缩dp
func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()
	var n, c, m int
	fmt.Fscan(reader, &n, &c, &m)
	type task struct {
		cpu int
		mem int
		val int
	}
	full := 1 << n
	validval := make([]int, full)
	tasks := make([]task, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &tasks[i].cpu, &tasks[i].mem, &tasks[i].val)
	}
	for mask := 0; mask < full; mask++ {
		csum, msum, vsum, temp := 0, 0, 0, mask
		len := bits.Len(uint(mask))
		for i := 0; i < len; i++ {
			if temp&1 == 1 {
				csum += tasks[i].cpu
				msum += tasks[i].mem
				vsum += tasks[i].val
			}
			temp = temp >> 1
		}
		if csum <= c && msum <= m {
			validval[mask] = vsum
		}
	}
	dp := make([][]int, n+1)
	for i := 0; i <= n; i++ {
		dp[i] = make([]int, full)
		for j := 0; j < full; j++ {
			dp[i][j] = -1
		}
	}
	dp[0][0] = 0
	for k := 1; k <= n; k++ {
		for mask := 1; mask < full; mask++ {
			sub := mask
			for sub > 0 {
				if validval[sub] != 0 {
					pre := mask ^ sub
					if dp[k-1][pre] != -1 {
						dp[k][mask] = fmax(dp[k][mask], dp[k-1][pre]+validval[sub])
					}
				}
				sub = (sub - 1) & mask
			}
		}
	}

	exact := make([]int, n+1)
	for k := 1; k <= n; k++ {
		best := 0
		for mask := 0; mask < full; mask++ {
			if dp[k][mask] > best {
				best = dp[k][mask]
			}
		}
		exact[k] = best
	}

	ans := make([]int, n+1)
	for k := 1; k <= n; k++ {
		if exact[k] > ans[k-1] {
			ans[k] = exact[k]
		} else {
			ans[k] = ans[k-1]
		}
		fmt.Fprintln(writer, ans[k])
	}

}
func fmax(a, b int) int {
	if a > b {
		return a
	}
	return b
}


发表于 2026-04-12 21:47:47 回复(0)