Solve( 3, 7); // 3
Solve(20,100); //9688804
//N人の候補者に対して、M人が投票する場合の、解を求める
function Solve(pN,pM)
{
const UB = pM;
var Answer = 0;
for(var I = 1 ; I <= UB ; I++){
if(pM % I == 0 && I * pN <= pM){
Answer += SolveHelepr(pN,pM,I);
}
}
document.write(pN , '人の候補者に' , pM , '人が投票する場合は、' , Answer , '通り<br>');
}
function SolveHelepr(pN,pM,pMin)
{
const UB = pM;
//場合の数[直近の投票数][残りの票数]
var PrevDP = DeriveDPArr(UB);
PrevDP[pMin][pM - pMin] = 1;
//document.write("初期設定<br>");
//DebugPrint(PrevDP,UB);
for(var I = 2 ; I <= pN ; I++){
var CurrDP = DeriveDPArr(UB);
for(var J = 0 ; J <= UB ; J++){
for(var K = 0 ; K <= UB ; K++){
if(PrevDP[J][K] == 0) continue;
for(var L = 0 ; L <= UB ; L++){ //倍率のループ
var NewJ = J + pMin * L;
var NewK = K - NewJ;
if(NewJ > UB) break;
if(NewK < 0) break;
CurrDP[NewJ][NewK] += PrevDP[J][K];
}
}
}
//document.write(I , "でのDP結果<br>");
//DebugPrint(CurrDP,UB);
PrevDP = CurrDP;
}
var WillReturn = 0;
for(var I = 2 ; I <= UB ; I++){
if(CurrDP[I][0] > 0)
WillReturn += CurrDP[I][0];
}
return WillReturn;
}
function DeriveDPArr(pUB)
{
var DPArr = new Array(pUB + 1);
for(var I = 0 ; I <= pUB ; I++){
DPArr[I] = new Array(pUB + 1);
DPArr[I].fill(0);
}
return DPArr;
}
//DPのデバッグ用
function DebugPrint(pArr,pUB)
{
for(var I = 0 ; I <= pUB ; I++){
for(var J = 0 ; J <= pUB ; J++){
document.write("pArr[" , I , "][" , J , "]=" , pArr[I][J] , " ");
}
document.write("<br>");
}
}