有100名学生的成绩,每个班级50人,要求两个班级的平均分越接近越好,如何分配两个班级?
用C++实现。
#include <iostream>
#include <cstring>
#include <ctime>
const int N=5000;
const int M=100;
const int K=50;
int A[N+1][M+1][K+1];
int B[N+1];
int Score[M+1];
using namespace std;
int main(int argc,char **argv){
srand(time(NULL));
Score[0]=0;
memset(A,0,sizeof(int)*(N+1)*(M+1)*(K+1));
for(int i=1;i<=M;i++)
Score[i]=rand()%41+60;
int k=0;
for(int i=1;i<=M;i++){
for(int j=0;j<=N;j++)
if(j+Score[i]<=2500 && k<=50 && A[j][i][k]+Score[i]<A[j][i][k]-Score[i])
A[j+Score[i]][i][k++]=A[j][i][k]+Score[i];
else
A[j][i][k]-=Score[i];
}
}
这是我的代码,麻烦之指出错误。应该是在状态转移方程那里。
这不是一个标准的 背包问题, 往上面套也挺费劲. 不如就当作一般的dp来处理好了.
也没太看懂你的程序. 我按我的理解写了一个java的.
首先求出 所有学生的 总成绩 / 2, 设为half, 此题 即为找出50个学生, 其总成绩最接近此 half值
.dp 表为
Set<Integer> dp[][] = new HashSet[N / 2 + 1][half + 1]; 对每一个dp[i][j], 即选出i个学生, 其总成绩最接近j; 每一个Set包含 此 i个学生在score数组中的下标
.只做了最简单的测试, 不保证程序完全正确.
用一维数组节省内存的做法: