[GeeksForGeeks] Count Number of ways to reach a given score in a game

Consider a game where a player can score 3 or 5 or 10 points in a move. Given a total score n, find the number of 

ways to reach the given score. 

Example:

Input n = 20

Output: 4

There are the following 4 ways to reach 20.

(10, 10)

(5, 5, 10)

(5, 5, 5, 5)

(3, 3, 3, 3, 3, 5)

 

 Solution 1. DFS + Backtracking

Since we do not consider the same combination with different ordering different ways, this problem is equivalent to a simpler 

version of Combination Sum II. The given set does not have duplicate values, and each element can be picked unlimited times.

Algorithm:

1. sort the input points array.

2.  start from the first element, recursively add it to the current selection and check if the remaining score can be obtained 

from the current considering element set. When startIdx is 0, we consider all elements, when it is 1, we exclude element 0 

as all cases that involves element 0 have been checked. 

 

The key point in the recursive call is that we do not advance the startIdx from i to i + 1 as each element can be picked unlimited times. 

 

 1 import java.util.ArrayList;
 2 import java.util.Arrays;
 3 
 4 public class CountWaysOfScore {
 5     private int ways = 0;
 6     private ArrayList<ArrayList<Integer>> results;
 7     public int getWaysofScore(int[] points, int score) {
 8         results = new ArrayList<ArrayList<Integer>>();
 9         if(score > 0 && (points == null || points.length == 0)) {
10             return 0;
11         }
12         if(score == 0) {
13             return 1;
14         }
15         Arrays.sort(points);
16         getWaysHepler(points, 0, score, new ArrayList<Integer>(), results);
17         return ways;
18     }
19     private void getWaysHepler(int[] points, int startIdx, int score, 
20                                 ArrayList<Integer> list, ArrayList<ArrayList<Integer>> results) {
21         if(score == 0) {
22             ways++;
23             results.add(new ArrayList<Integer>(list));
24             return;
25         }
26         else if(points[startIdx] > score) {
27             return;
28         }
29         int remainScore = score;
30         for(int i = startIdx; i < points.length; i++) {
31             remainScore -= points[i];
32             list.add(points[i]);
33             getWaysHepler(points, i, remainScore, list, results);
34             remainScore += points[i];
35             list.remove(list.size() - 1);
36         }
37     }
38     public static void main(String[] args) {
39         int[] points = {3, 5, 10};
40         CountWaysOfScore test = new CountWaysOfScore();
41         System.out.println(test.getWaysofScore(points, 20));
42         for(int i = 0; i < test.results.size(); i++) {
43             for(int j = 0; j < test.results.get(i).size(); j++) {
44                 System.out.print(test.results.get(i).get(j) + " ");
45             }
46             System.out.println();
47         }
48     }
49 }

 

Solution 2. Dynamic Programming 

State: T[i][j]: the total ways of score i for given the first j elements points[0.....j - 1]

Function: if points[j - 1] <= i, it means the current point[j - 1] can be possibly used: T[i][j] = T[i - points[j - 1]][j] + T[i][j - 1];

     if not, then points[j - 1] can not be used: T[i][j] = T[i][j - 1];

Initialization: T[0][j] = 1;  if score is 0, then there is 1 way to get 0 by not picking anything.

      T[i][0] = 0, i >= 1; if score is bigger than 1 and we don't have any elements to pick, there is 0 way.

Answer: T[score][points.length]

 

 1 public int getWaysOfScoreDp(int[] points, int score) {
 2     if(points == null || score < 0) {
 3         return 0;
 4     }
 5     int[][] T = new int[score + 1][points.length + 1];
 6     for(int j = 0; j <= points.length; j++) {
 7         T[0][j] = 1;
 8     }
 9     for(int i = 1; i <= score; i++) {
10         T[i][0] = 0;
11     }
12     for(int i = 1; i <= score; i++) {
13         for(int j = 1; j <= points.length; j++) {
14             if(points[j - 1] <= i) {
15                 T[i][j] = T[i - points[j - 1]][j] + T[i][j - 1];
16             }
17             else {
18                 T[i][j] = T[i][j - 1];
19             }
20         }
21     }
22     return T[score][points.length];
23 }

 

 

Follow up question: instead of only return the total number of ways, hwo about return all possible ways?

 

Related Problems

Combination Sum
Combination Sum II

转载于:https://www.cnblogs.com/lz87/p/7462911.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值