//暴力轮询的方法
int process1(int arr,int index,int aim)
{
int res = 0;
if(index == arr.size())
{
res = aim == 0?1:0//退出条件
}
else
{
for(int i=0;arr[index] * i <=aim;i++)
{
res += process1(arr,index+1,aim-arr[index]*i)
}
}
return res;
}
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|--------------------------------------------
5 | 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
3 | 1 0 0 0 0 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 2
2 | 1 0 0 0 0 1 1 1 2 2 3 4 4 5 6 7 8 9 10 11 13
*/
int changeFormoney()
{
int aim = 20;
int money[3] = {5,3,2};
int i,j;
int dp[3][21]={{0,},{0,}};
for(i=0;i<3;i++)
{
dp[i][0] = 1;//钱数为零时,只有一种方法,就是每一种都为0
}
/*dp[i][j]代表什么?存在money[0...i]种货币组成j元的种数*/
/*先组合第一行*/
for(j=0;j<=aim;j++)
{
dp[0][j*money[0]]=1;
}
int numm = 0,k=0;//记录不用此面值钞票剩下的
for(i=1;i<3;i++)
{
for(j=1;j<=aim;j++)
{
numm = 0;
for(k=0;j-money[i]*k>0;k++)//使用money[i]这种货币从1张到k张时的所有的方法总和3
{
numm += dp[i-1][j-money[i]*k];//j-money[i]*k可以这么理解,比如j=8,此时用0个3,组不成;用一个3,需要一个5,查看上一行面值为5的是否可以,发现dp[0][5]等于1,可以组成
}
dp[i][j] = numm;//不为0的位置就是可以组成的位置,在比如i=2,还是j=8.使用0个2,查看dp[1][8]为1,可以组成;使用一个2,查看dp[1][6]位0,组不成;使用两个2,查看dp[1][4]组不成;一次类推在dp[0][0]出还可以此时使用了4个2;
} //dp[1][8]+dp[1][6]+dp[1][4]+dp[1][2]+dp[1][0]
} //dp[i-1][j-money[i]*k]
printf("\r\n");
for(i=0;i<3;i++)
{
for(j=0;j<=aim;j++)
{
printf("%d ",dp[i][j]);
}
printf("\r\n");
}
return 0;
}
换钱的方法数
最新推荐文章于 2020-12-04 15:11:35 发布