挑戰程序設計競賽筆記_P55

//理解的時候一定要看打出來的表理解!!!

#include 
#include 
#define max(a, b) a > b ? a : b
const int MAX_N = 100;
const int MAX_W = 10000;
int n, W, w[MAX_W], v[MAX_N], dp[MAX_N + 1][MAX_W + 1];
int rec1(int i, int j)
{
    memset(dp, -1, sizeof(dp));
    if (dp[i][j] >= 0)
        return dp[i][j];
    if (i == n)
        return 0;
    if (j < w[i])
        return dp[i][j] = rec1(i + 1, j);
    else
        return dp[i][j] = max(rec1(i + 1, j), rec1(i + 1, j - w[i]) + v[i]);
}
int rec2(int i, int j)
{
    memset(dp, -1, sizeof(dp));
    if (dp[i][j] >= 0)
        return dp[i][j];
    if (i == 0)
        return 0;
    if (j < w[i - 1])
        return dp[i][j] = rec2(i - 1, j);
    else
        return dp[i][j] = max(rec2(i - 1, j), rec2(i - 1, j - w[i - 1]) + v[i - 1]);
}
int arr1()
{
    memset(dp, 0, sizeof(dp));
    for (int i = n - 1; i >= 0; i--)
    {
        for (int j = 1; j <= W; j++)
        {
            if (j < w[i])
                dp[i][j] = dp[i + 1][j];
            else
                dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - w[i]] + v[i]);
        }
    }
    return dp[0][W];
}
int arr2()
{
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= W; j++)
        {
            if (j < w[i - 1])
                dp[i][j] = dp[i - 1][j];
            else
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i - 1]] + v[i - 1]);
        }
    }
    return dp[n][W];
}
int arr3()
{
    //數組方法3,同2
    memset(dp, 0, sizeof(dp));
    for (int i = 0; i < n; i++)
    {
        for (int j = 1; j <= W; j++)
        {
            if (j < w[i])
                dp[i + 1][j] = dp[i][j];
            else
                dp[i + 1][j] = max(dp[i][j], dp[i][j - w[i]] + v[i]);
        }
    }
    return dp[n][W];
}
int arr4(){
    memset(dp, 0, sizeof(dp));
    for (int i = 0; i < n; i++){
        //這裏從j=1開始不行!!因爲dp[i+1][j+w[i]]中j=0是有用的!而之所以前面的那些個數組方法可以,是因爲他們根本用不着j=0來推斷右下的元素
        for (int j = 0; j <= W; j++){
            if (w[i] + j <= W){
                dp[i + 1][j + w[i]] = dp[i][j] + v[i];
            }
            dp[i + 1][j] = max(dp[i][j], dp[i + 1][j]);
            // if (w[i] + j <= W){
            //     dp[i + 1][j + w[i]] = max(dp[i + 1][j + w[j]], dp[i][j] + v[i]);
            // }//這個改動是不是666?
        }
    }
    return dp[n][W];
}
void print()
{
    printf(" i\\j");
    for (int i = 0; i <= W; i++)
        printf("%4d", i);
    putchar(10);
    for (int i = 0; i <= n; i++)
    {
        printf("%4d", i);
        for (int j = 0; j <= W; j++)
            printf("%4d", dp[i][j]);
        putchar(10);
    }
    putchar(10);
}
int main()
{
    freopen("E:/My/input.txt", "r", stdin);
    scanf("%d%d", &n, &W);
    for (int i = 0; i < n; i++)
        scanf("%d%d", w + i, v + i);

    printf("arr1:%d\n", arr1());
    print();

    printf("arr2:%d\n", arr2());
    print();

    printf("arr3:%d\n", arr3());
    print();

    printf("arr4:%d\n", arr4());
    print();

    // printf("rec1:%d\n", rec1(0, W));
    // print();

    // printf("rec2:%d\n", rec2(n, W));
    // print();

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章