使用动态编程改变硬币

时间:2016-04-18 14:20:25

标签: java dynamic-programming

硬币改变是一个受欢迎的采访问题。基本上这个问题意味着给出一组硬币面额,总共有多少种方式可以得到总数,并且每种面额都可以无限供给。

这是我的代码。 逻辑是每次我选择一个硬币,问题就会减少到解决总数减去硬币的问题。

public static int numberOfWays(int total, int[] options){

        int[][] memo = new int[options.length][total+1];

        for (int i = 0; i <memo.length ; i++) {

            for (int j = 0; j <memo[i].length ; j++) {

                if(i == 0)  memo[i][j] = 1;
                else if(options[i] > j ) memo[i][j] = memo[i-1][j];
                else memo[i][j] = memo[i-1][j] + memo[i][j - options[i]];
            }
        }
        return memo[options.length-1][total];
    }

这适用于total = 5 and options = 1, 2, 3的测试用例 但是total = 10 and options = 2, 5, 3, 6

失败了

有人可以帮我理解我做错了什么。

1 个答案:

答案 0 :(得分:4)

首先,写出每个数组元素代表什么的陈述是好的:

  

memo[i][j]表示只有多少种方法可以使joptions[0],...,options[1]中的硬币只有options[i]。< / p>

现在,你似乎已经得出了一些法则:

    对于所有memo[0][j]
  1. 1j 每当i
  2. 时,memo[i][j]大于0,memo[i-1][j]options[i] > j相同
  3. i大于0,memo[i][j]只要memo[i-1][j] + memo[i][j - options[i]]
  4. options[i] <= j

    你的问题是这些法律中的第一个是不正确的。 (第二个是)

    如果memo[0][j]1,则“j options[0]对所有1”的声明仅适用。如果options[0]不是1,则当memo[0][j]j的倍数时,options[0]为1,而当2不是memo[0][5] == 0时,memo[0][5] == 1为1。仅使用面额为 if(i == 0) { if (j % options[i] == 0) memo[i][j] = 1; else memo[i][j] = 0; } else if(options[i] > j ) memo[i][j] = memo[i-1][j]; else memo[i][j] = memo[i-1][j] + memo[i][j - options[i]]; 的硬币,你不能赚5美分,所以你应该(使用第二组数据)if,但你的程序说else。然后抛弃所有后续计算。

    所以我修改你的程序说:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final ScrollView sv = (ScrollView) findViewById(R.id.scrollView);
    
        // Setup the MapView
        mapView = (MapView) findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
    
        // ....
    
        mapView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_MOVE:
                        sv.requestDisallowInterceptTouchEvent(true);
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        sv.requestDisallowInterceptTouchEvent(false);
                        break;
                }
                return mapView.onTouchEvent(event);
            }
        });
    

    (虽然在纯粹的文体上,我发现ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:mapbox="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.cameron.mapboxplayground.MainActivity" android:id="@+id/scrollView"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- Set the starting camera position and map style using xml--> <com.mapbox.mapboxsdk.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="500dp" mapbox:access_token="@string/accessToken" mapbox:style_url="@string/style_light" mapbox:center_latitude="40.7359" mapbox:center_longitude="-74.0151" mapbox:zoom="10"/> </LinearLayout> </ScrollView> / {{1}}语句即使对于单个语句也不使用大括号,但却要求错误。

相关问题