Java 列出具有约束的集合中所有可能和的总和
我很想了解以下情况: 给定一个有N个元素的集合,我和我的朋友在玩一个游戏。我总是先发制人。 我们只能移除第一个或最后一个元素,每个元素都有50%的几率。我们在游戏中轮流进行。如果只剩下一个元素,我们可以肯定地移除它。我可以收集的预期金额是多少Java 列出具有约束的集合中所有可能和的总和,java,math,recursion,probability,expectations,Java,Math,Recursion,Probability,Expectations,我很想了解以下情况: 给定一个有N个元素的集合,我和我的朋友在玩一个游戏。我总是先发制人。 我们只能移除第一个或最后一个元素,每个元素都有50%的几率。我们在游戏中轮流进行。如果只剩下一个元素,我们可以肯定地移除它。我可以收集的预期金额是多少 For example:N=2 {10,20} Possible sets that I can collect are {10},{20}. So expected sum is 0.5*10+0.5*20=15. 我的做法: 由于得到一个可能和的概率
For example:N=2 {10,20} Possible sets that I can collect are {10},{20}.
So expected sum is 0.5*10+0.5*20=15.
我的做法:
由于得到一个可能和的概率在所有情况下都是相等的,我们只需要计算所有可能和的和,然后乘以0.5^N/2
我尝试使用递归计算所需的和:
f(i,j)-computes the sum between i and j recursively
f(i,j)=2*a[i]+func(i,j-2)+func(i+1,j-1)+func(i+1,j-1)+func(i+2,j)+2*a[j]);
Initial call f(1,N)
但这种方法似乎不起作用。我该怎么办
完整功能如下:
class CandidateCode {
static long v[][] = new long[1003][1003];
public static long func(int a[], int i, int j) {
if (i == j)
return v[i][j] = a[i];
if (v[i][j] != 0)
return v[i][j];
else {
if (i > j - 2 && i + 1 > j - 1 && i + 2 > j)
return (v[i][j] += 2 * a[i] + 2 * a[j]);
else
return (v[i][j] += 2 * a[i] + func(a, i, j - 2) + func(a, i + 1, j - 1) + func(a, i + 1, j - 1)
+ func(a, i + 2, j) + 2 * a[j]);
}
}
public static void main(String args[]) {
int n;
int a[] = { 0, 6, 4, 2, 8 };
n = a.length - 1;
System.out.println(func(a, 1, 4) / Math.pow(2, n / 2));
}
}
这个问题可以通过应用动态规划来解决 首先,游戏的状态是player,start,end,这表示当前玩家,以及原始集合中可用的值的范围。在开始时,我们从玩家0开始,开始是0,结束是N-1 表示第一个玩家是0,第二个玩家是1,我们有玩家0的期望值:
if(player == 0){
double result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
}else{
double result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
}
因此,对于每个状态,我们可以将所有计算出的状态存储在dp[player][start][end]表中,这将时间复杂度降低到O2*N*N,其中N是集合中的数值
伪代码:
double expectedValue(int player, int start, int end, int[]set){
if(start == end)
if(player == 0)
return set[start];
return 0;
if(already calculated this state)
return dp[player][start][end];
double result= 0;
if(player == 0){
result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
}else{
result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
}
return dp[player][start][end] = result;
}
NWe只能以50%的概率移除第一个或最后一个元素,这意味着在每一轮中,您可以获得第一个或最后一个元素,但始终保证获得1,就像掷硬币一样,你也可以选择,你得到你选择的东西的几率是50%?我们可以选择第一个或最后一个元素,概率是1/2。是的,我们保证每回合得到一个元素@Pham trung没有得到游戏规则,但要解决标题中提到的问题:获得所有的数字幂集,有现有的算法,然后检查每个组合的前提条件。如果它成立,计算总和。仅此而已。N=1000如何使用电源设置无法理解..你能详细说明吗?@rajarshi369在哪部分你不理解?在dp@rajarshi369我们首先从一个完整的集合开始,所以我们只能取出位置0或位置N-1处的元素,所以下一个状态只能是start+1,end或start,end-1,对吗?玩家轮流,所以玩家0->玩家1->玩家0…@rajarshi369,我们只需要关心玩家0,所以只需要在结果中添加玩家==0的值,就这样!