经典的海盗分钱问题,原题在这里有描述:http://edward-mj.com/page/2
动态规划方案:
m个海盗
n[i][j] : 保存当由海盗i来分钱时,海盗j能得到的钱数(j>=i)
然后 在海盗i-1分钱时,当且仅当 分给海盗j( j>i )的钱数n[i-1][j] > n[i][j],才能够获得海盗j的支持。
注意,考虑一种复杂情况,当用户i 分钱怎么分都是死的时候,可以设置n[i][i] = -1. 即看作用户i只要保命就行。这种情况下,就算i-1不给i钱,i也会支持i-1. 因此n[i-1][i] =-1+1=0即可。而设置 n[i][j(j>i)]=n[i+1][j],即因为海盗i必死,所以海盗j能够获得的钱数将由i+1海盗决定
于是,对i-1海盗:
- TN(总钱数) = n[i-1][i-1] + sum( n[i-1][j] = n[i][j] +1 or 0, j=1~m, j!=i-1 ), 并要求取n[i][j]+1的次数>=(m-i+2)/2
- 如果上述方案不存在,则 n[i-1][i-1]=-1(无法保命), n[i-1][j (j>i-1) ] = n[i][j]
n[ m ] [ m ]= TN(如果只剩下一个海盗m,则他将获得所有金币)
for i=m-1 to 1:
memset( num , -1, sizeof...
num[w=0]=v=0 //w 为获得票数(不包括自己),v 为需要的金币数量
for j = i+1 to m:
for w = m-k+1 to 1:
if num[w] == -1 or num[w] > num[w-1] + n[i+1][j] :
lst[w]=j, num[w]=..... //获得j的支持,获得w票
if num[ (m - i + 2) /2 ] != -1 && num[ (m - i + 2) /2 ] <= TN: / /存在分配方案
for j = i+1 to m:
n[i][j] = n[i+1][j] + 1 or 0 //每个海盗d的金币数量
n[i][i] = TN - nu