题意:题目大意是说n个人做m项工程,然后给出工人的薪水,和工程按期完工的概率,以及按时完工的酬劳和未按时完工的罚款,要求出最大利润。。需要注意的 是,薪水输出的是欧元为单位,输出的是以分为单位。
解题思路:简单的背包问题,dp[i][j]表示前i个工程,分配j个人完成的最大期望利润。dp[i][j] = max{dp[i-1][k] + cost}, 0 <= k <= j
这道题的利润可能为负,所以初始化不能直接赋0,这里WA了一次。总体不是很难,看懂题意就比较简单了。
#include<iostream>
#include<cstdio>
#include<cstring>
#define max(a,b) a > b ? a : b
const int maxn = 105;
const int inf = 0x7fffffff;
int n,m,salary,p[maxn][maxn];
int reward[maxn],punish[maxn];
int dp[maxn][maxn]; //dp[i][j]表示前i个项目共j人做得到的最大利润
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&m,&n,&salary); //m个项目,n个人
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
scanf("%d",&p[i][j]);
scanf("%d%d",&reward[i],&punish[i]);
}
for(int i = 0; i <= m; i++)
for(int j = 0; j <= n; j++) dp[i][j] = -inf;
for(int i = 0; i <= n; i++)
dp[1][i] = p[1][i] * (reward[1] - i * salary) - (100 - p[1][i]) * punish[1];
for(int i = 2; i <= m; i++)
for(int j = 0; j <= n; j++)
for(int k = 0; k <= j; k++)
{
dp[i][j] = max(dp[i][j],dp[i-1][j-k] + p[i][k] * (reward[i] - k * salary) - (100 - p[i][k]) * punish[i]);
}
int ans = -inf;
for(int i = 0; i <= n; i++)
ans = max(ans,dp[m][i]);
printf("%d\n",ans);
for(int i = 0; i <= n; i++)
if(ans == dp[m][i])
printf("%d ",i);
printf("\n");
}
return 0;
}