01背包--hdu

hdu1203

思路:计算一个offer都没有的概率,容斥一下

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>

using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e4 + 100;
const int MOD = 1e9 + 9;

#define lson l, m, rt << 14
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i)

int n, m, a[N];
double b[N], dp[N];
int main()
{
    while(cin >> n >> m)
    {
        if(!n && !m) break;
        memset(a, 0, sizeof(a));
        fill(b, b + N, 0);
        fill(dp, dp + N, 1);
        F(i, 1, m) {cin >> a[i] >> b[i];b[i] = 1 - b[i];}
        for(int i = 1;i <= m;++i)
            for(int j = n;j >= a[i];--j)
            dp[j] = min(dp[j], dp[j - a[i]] * b[i]);
        printf("%.1f%%\n", (1 - dp[n]) * 100);
    }
    return 0;
}

hdu 2602

经典01背包

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>

using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e4 + 100;
const int MOD = 1e9 + 9;

#define lson l, m, rt << 14
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i)

int n, m, v[N], w[N], dp[N];
int main()
{
    int T;cin >> T;
    while(T--)
    {
        cin >> n >> m;
        if(!n && !m) break;
        fill(v, v + N, 0);
        fill(w, w + N, 0);
        fill(dp, dp + N, 0);
        F(i, 1, n) cin >> w[i];
        F(i, 1, n) cin >> v[i];
        for(int i = 1;i <= n;++i)
            for(int j = m;j >= v[i];--j)
            dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
        cout << dp[m] << endl;
    }
    return 0;
}

hdu1171

多个相同设备看成独立的一个物品,背包容量为所有设备价值总和的一半

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>

using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 100;
const int MOD = 1e9 + 9;

#define lson l, m, rt << 14
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i)

int dp[N], v[N], w[N], n;
int main()
{
    while(cin >> n)
    {
        if(n < 0) break;
        memset(dp, 0, sizeof(dp));
        int m = 0;
        F(i, 1, n) {cin >> w[i] >> v[i];m += v[i] * w[i];}
        F(i, 1, n)
            for(int j = m / 2;j >= w[i];--j)
                for(int k = 1;k * w[i] <= j && k <= v[i];++k)
                    dp[j] = max(dp[j], dp[j - k * w[i]] + k * w[i]);
        cout << m - dp[m/2] << " " << dp[m / 2] << endl;
    }
    return 0;
}

hdu 6376

思路:每个连续的子串‘1’价值为‘1’的个数,费用为裁剪的次数
最左最右裁一刀,中间两刀
把问题转换成裁剪k+1刀,k+2段纸组成最长的连续的‘1’
特判k=0

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>

using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 100;
const int MOD = 1e9 + 9;

#define lson l, m, rt << 14
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i)

string s;
int dp[N];
int main()
{
    int n, k;
    while(cin >> n >> k >> s)
    {
        int len = s.size(), t = 0;
        memset(dp, 0, sizeof(dp));
        vector<int> v, w;
        F(i, 0, len - 1)
        {
            if(s[i] == '1') t++;
            else if(t)
            {
                v.push_back(t);
                w.push_back(2);
                t = 0;
            }
        }
        if(t) {v.push_back(t);w.push_back(1);}
        if(k == 0)
        {
            if(s[0] == '1') cout << v[0] << endl;
            else cout << 0 << endl;
            continue;
        }
        if(s[0] == '1') w[0] = 1;
        len = v.size();k++;
        F(i, 0, len - 1)
            for(int j = k;j >= w[i];--j)
            dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
        cout << dp[k] << endl;
    }
    return 0;
}

posted @ 2019-05-23 23:05  谁知道你啊啊啊  阅读(265)  评论(0编辑  收藏  举报