cf366 C. Dima and Salad(01背包变式)
题意:
n 个物品,每个物品有属性 \(a_i,b_i\)。选择若干物品,要求所选物品 \(\frac {\sum a_i}{\sum b_i}=k\) ,并且最大化 \(\sum a_i\) ,输出最大值。
$1\le n,a_i,b_i\le 100, 1\le k\le 10, $ 都是整数
思路:
限制条件化为 \(\sum (a_i-kb_i)=0\)
就是01背包,物品体积为 \(c_i=a_i-kb_i\),价值为 \(a_i\)
要求所选物品的体积和为0,背包容量 \(1e4\)
初始化 \(f(0)=0\),其他为负无穷
物品体积可能为负,可以加个1000。也可以用 \(f,g\) 分别处理正的体积和负的体积
const int N = 110, C = 1e4;
int n, k, a[N], b[N];
int f[C + 3], g[C + 3]; //要开到最大容量
signed main()
{
    cin >> n >> k;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) cin >> b[i];
    memset(f, -INF, sizeof f), f[0] = 0;
    memset(g, -INF, sizeof g), g[0] = 0;
    for(int i = 1; i <= n; i++)
    {
        int c = a[i] - k * b[i];
        if(c >= 0) //正的体积
            for(int j = C; j >= c; j--)
                f[j] = max(f[j], f[j-c] + a[i]);
        else //负的
            for(int j = C; j >= -c; j--)
                g[j] = max(g[j], g[j+c] + a[i]);
    }
    int ans = 0;
    for(int i = 0; i <= C; i++)
        ans = max(ans, f[i] + g[i]);
    cout << (ans ? ans : -1);
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号