问题陈述:
您将获得两个数字,即A和S.编写程序以查找可以添加大于或等于S的数字的方式的数量以获得总和A.以模10的形式打印结果^ 9 + 9
e.g。如果A为3且S为1,则有三种方法可以使用大于等于S = 1的数字来实现A = 3。溶液是< 1,1,1>,< 1,2>。和< 3>。 对于A = 9和S = 3,溶液将是< 3,3,3>,< 3,6>,< 4,5>。和< 9>。共有4种方法可以使用大于等于3的数字来获得9。
我使用了以下方法。
对于列表中的每个号码。
3.1。而A> = i
3.1.1。通过i减少A.
3.1.2。如果A> = i,则增加计数(计数存储总排列,并且是 最初设为1)。
3.1.3。否则就会退出。
这种方法具有二次时间复杂度。有没有更好的方法来解决这个问题?
答案 0 :(得分:0)
我能够使用动态编程解决这个问题。问题类似于硬币变化问题,其中总和是我们的总金额,d,d + 1,d + 2,..,sum是我们可用于实现总和的硬币。下面是我写的java代码。
private static int countPartitionsDP(int d, int sum){
if(d>sum/2)
return 1;
if(d>sum)
return 0;
int coins=sum-d+1;
int[][] dp=new int[coins][sum+1];
for(int i=0;i<coins;i++){ //for sum=5 and d=2 number that we use to achieve sum is 2,3,4,5 i.e (i+d).
for(int j=0;j<=sum;j++){
if(j==0) //sum=0 can be achieved in 1 way. dp[i][0]=1
dp[i][j]=1;
else if(i==0){
if(j<(i+d)){ //if current sum j is less than current value of d i.e.(i+d).
dp[i][j]=0;
}else{
dp[i][j]=dp[i][j-i-d]; //if sum is greater than current value of d then dp[i][j]=dp[i][j-d]
}
}else if(j<(i+d)){
dp[i][j]=dp[i-1][j];
}else{
dp[i][j]=dp[i-1][j]+dp[i][j-i-d];
}
}
}
return dp[coins-1][sum];
}