当前队伍数量: applyNum
当前专家数量: expertNum
每位专家最多评审队伍数量: expertMax
每个队伍所需专家数量: teamExpertMax
问:每队可分配到专家几人,每个专家可评审队伍数量几个?
只要有一个变量变了,那么其它变量的可用值范围也变了,所以对应的公式应该是什么样的
当前队伍数量: applyNum
当前专家数量: expertNum
每位专家最多评审队伍数量: expertMax
每个队伍所需专家数量: teamExpertMax
问:每队可分配到专家几人,每个专家可评审队伍数量几个?
只要有一个变量变了,那么其它变量的可用值范围也变了,所以对应的公式应该是什么样的
你有没有想过,其实你的这个问题本身就不应该用动态规划,本身就不存在什么转移方程。
解决这个问题,贪心法是适当且可用的方法。
在此用c#写一个例子,虽然不是java,但是我写了很详细的注释来阐明这个思路。希望有帮助。
namespace ConsoleApp3
{
internal class Program
{
static void Main(string[] args)
{
int[] num1 = { 3, 2, 6, 4, 1, 5, 3, 2, 2, 4 };//每个队伍所需的专家数,数组长度对应队伍数
int[] num2= { 3, 2, 6, 4, 1, 5 };//每个专家能够接待的队伍数,数组长度对应专家数
int[] num11 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };//用于存储每个队伍被选中的情况,1代表被评审,该列表显然长度等于num11
int[] num22 = { 0,0,0,0,0,0 };//用于存储每个专家已接待的队伍数,显然该列表长度等于num2
int count = 0; //最大评审队伍数量
//因为目标是要能评审的队伍数最多,显然我们应该优先选择占用专家数最小的队伍
while (true)//在循环内进行计算解题
{
int min = 999999999;//用于存储所需专家数最小的队伍所需的专家,在此初值赋一个特别大的数(只要大于所需专家的最大数就行)
int tmp=0;//尚未被接待的队伍中所需专家数最少的队伍的索引
for (int i = 0; i < num1.Length; i++)//遍历各个队伍
{
if (num11[i]==0)//如果该队伍尚未被接待
{
if (min>num1[i])
{
min = num1[i];//更新尚未被接待队伍所需的最小专家数
tmp = i;
}
}
}
num11[tmp] = 1;//更新被选中的队伍状态
int tmp2 = 0;//专家可以接待的最大队伍数
for (int i = 0; i < num2.Length; i++)//遍历专家
{
if (num22[i]<num2[i])//表明该专家尚未接待满
{
tmp2++;
}
}
if (tmp2 < num1[tmp])//如果当前可接待的专家数小于所需专家最小的队伍的数量
{
break;//说明以达到最大的接待能力,计算跳出
}
else//如果没有超出接待能力,则选择出专家
{
int[] tmp3 = { 0, 0, 0, 0, 0, 0 };//用于存储在这一轮选择中,每个专家的选择情况,该数组长度等于num2
int tmp5 = num1[tmp];//存储当前选择的队伍需要的专家数
while (true)//在循环内选择专家
{
int max = 0;//存储剩余接待能力最大的专家的剩余接待数
int tmp4 = 0;//存储专家索引
for (int i = 0; i < num2.Length; i++)
{
if (tmp3[i]==0 && max<num2[i]-num22[i])//如果该专家此轮尚未被选择且剩余接待能力大于max,更新max
{
max = num2[i] - num22[i];
tmp4 = i;
}
}
tmp3[tmp4] = 1;//选择该专家
num22[tmp4]++;//该专家目前已服务的队伍数+1
tmp5--;//队伍所需专家数减一
if (tmp5==0)//专家已分配完
{
break;//跳出循环
}
}
}
int tmp6 = 0;//存储已选择的队伍数
for (int i = 0; i < num1.Length; i++)
{
if (num11[i]==1)
{
tmp6++;
}
}
if (tmp6==num1.Length)//如果所有队伍已选择
{
break;//跳出
}
}
for (int i = 0; i < num1.Length; i++)
{
if (num11[i] == 1)
{
count++;
}
}
Console.WriteLine(count);//打印最大队伍数量
Console.ReadKey();
}
}
}