基础dp(2)补充

完全背包:

有N种物品和一个容量为V的背包,每种物品都有无限件可用。

根据01背包的状态转移方程我们可以得知:

dp(i,j)=max(dp(i-1,j),dp(i-1,j-v[i])+val[i])

这里因为01背包每种物品只有一件可用,所以只有选一个这个物品和不选这一个物品两个选择。如果这个物品数量变为无限个,那么就有不选这个物品、选一个这个物品、选两个、三个......k个这些可能。而这些可能可以用下一个状态dp(i,j-v)+w来表示

即dp(i,j-v)=max( dp(i-1,j-v) , dp(i-1,j-2v)+w,dp(i-1,j-3v)+2w , dp(i-1,j-4v)+3w......k , dp(i-1,j-kv)+(k-1)w) )。

所以我们得出完全背包的状态转移方程:dp(i,j)=max(dp(i-1,j),dp(i,j-v)+w)。

优化成一维之后为:dp[j]=max(dp[j],dp[j-v]+w)。

eg:https://www.luogu.com.cn/problem/P1616

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;

long long a[10010],b[10010];
long long dp[10000010];

int main()
{
    long long t,m;
    scanf("%lld %lld",&t,&m);
    for(int i=1;i<=m;i++){
        scanf("%d %d",&a[i],&b[i]);
    }
    for(int i=1;i<=m;i++){
        for(int j=a[i];j<=t;j++){
            dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
        }
    }
    printf("%lld
",dp[t]);
    return 0;
 } 

(注意long long)

EOF

原文地址:https://www.cnblogs.com/Untergehen/p/15379280.html