2015 CCPC D- Pick The Sticks(UESTC 1218) (01背包变形)

http://acm.uestc.edu.cn/#/problem/show/1218

既然二维dp表示不了,就加一维表示是否在边界放置,放置一个,两个。有一个trick就是如果只放一根,那么多长都可以。

wa了好多次(囧)

开始因为l[i]/2会出现小数,没注意,把所有的长度都x2就可以解决。

又wa了n次因为没注意j-l[i]时没加判断,为什么不是RE呢!不开心。。。

/*********************************************
Memory: 1140 KB		Time: 3976 MS
Language: C++		Result: Accepted
*********************************************/
#include <iostream>
#include <cstring>

using namespace std;

typedef long long ll;

int l[1005];
int v[1005];
ll dp[4005][5];

int main()
{
    int t;
    cin >> t;
    int cas = 0;
    while (t--)
    {
        cas++;
        int n, L;
        cin >> n >> L;
        L *= 2;
        ll ans = 0;
        for (int i = 0; i < n; ++i)
        {
            cin >> l[i] >> v[i];
            l[i] *= 2;
            ans = max(ans, (ll)v[i]);
        }
        memset(dp, 0, sizeof dp);
        for (int i = 0; i < n; ++i)
        {
            for (int j = L; j >= l[i] / 2; --j)
            {
                dp[j][2] = max(dp[j][2], dp[j - l[i] / 2][1] + v[i]);
                if (j >= l[i]) dp[j][2] = max(dp[j][2], dp[j - l[i]][2] + v[i]);
                dp[j][1] = max(dp[j][1], dp[j - l[i] / 2][0] + v[i]);
                if (j >= l[i]) dp[j][1] = max(dp[j][1], dp[j - l[i]][1] + v[i]);
                if (j >= l[i]) dp[j][0] = max(dp[j][0], dp[j - l[i]][0] + v[i]);
            }
        }
        ans = max(ans, dp[L][2]);
        cout << "Case #" << cas << ": " << ans << endl;
    }
    return 0;
}

/**
Input:
50
2 3
1 2
2 3

3 7
4 1
2 1
8 1

3 7
4 2
2 1
8 4

3 5
4 1
2 2
8 9

1 1
10 3



Output:
5
2
6
11
3

*/

  

posted @ 2015-10-30 20:02  我不吃饼干呀  阅读(422)  评论(0编辑  收藏  举报