动态规划两题

第一道
洛谷P2760
根据题目意思能显然看出是个多重背包问题,不过就是在背包的容量上有点图书要求而已
,预处理稍微写的比较臃肿,实际上有思维含量的代码很少

#include 

using namespace std;
#define N  110
#define ll long long
struct Obj
{
    ll val,num,cost;
};
Obj mat[N][N];
Obj obj[N*N];
ll dp[N];
int main()
{
    ll n,m,a,t,w;
    ll cnt=0;
    cin>>n>>m>>t>>a;
    w=t>a?a:t;
    for(register int i=1;i<=n;i++)
    {
        for(register int j=1;j<=m;j++)
        {
            cin>>mat[i][j].val;
            mat[i][j].cost=i+j;
        }
    }
    for(register int i=1;i<=n;i++)
    {
        for(register int j=1;j<=m;j++)
        {
            cin>>mat[i][j].num;
        }
    }
    for(register int i=1;i<=n;i++)
    {
        for(register int j=1;j<=m;j++)
        {
            if(mat[i][j].val!=0)
            {
                obj[++cnt].val=mat[i][j].val;
                obj[cnt].cost=mat[i][j].cost*2ll;
                obj[cnt].num=mat[i][j].num;
            }
        }
    }
    for(int i=1;i<=cnt;i++)
    {
        ll num1=min(obj[i].num,w/obj[i].cost);
        for(int k=1;num1>0;k<<=1)
        {
            if(k>num1)
                k=num1;
            num1-=k;
            for(int j=w;j>=obj[i].cost*k;j--)
            {
                dp[j]=max(dp[j],dp[j-obj[i].cost*k]+obj[i].val*k);
            }
        }
    }
    if(t<a)
    {
        cout<<dp[w]<<endl;
    }
    else
    {
        cout<<dp[w-1]<<endl;
    }
    return 0;
}

第二道
洛谷P1717
线性DP,根据题目给出的条件能比较容易想到DP状态
dp[i][j] 代表前i个池塘花费j个5分钟最多能钓上来几条鱼

转移方程
想着i和i-1是线性链接的,所以用这个点为突破口
dp[i][j]=max(dp[i][j],dp[i-1][j-t[i-1]-k]+k* f[i]-k*(k-1)/2*d[i])

也就是说,前i-1个池塘花省下了t[i-1]+k个时间单位给第i个池塘来钓鱼,有点像背包吧哈哈哈

注意:前i-1个池塘如果剩不下来t[i-1]+k个时间单位就不能硬在第i个池塘上花费t[i-1]+k个时间单位了

#include 
using namespace std;
#define ll long long
#define N 30
ll dp[N][16*60+100];
ll t[N],f[N],d[N];
int main()
{
    freopen("in.txt","r",stdin);
    ll h,n,ans=0;
    cin>>n>>h;
    h*=12ll;
    for(int i=1;i<=n;i++)
        cin>>f[i];
    for(int i=1;i<=n;i++)
        cin>>d[i];
    for(int i=1;i<=n-1;i++)
        cin>>t[i];
    memset(dp,-1,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=h;j++)
        {
            for(int k=0;k<=j-t[i-1];k++)
            {
                if((k-1)*d[i]<f[i]&&dp[i-1][j-t[i-1]-k]!=-1)
                {
                    dp[i][j]=max(dp[i][j],dp[i-1][j-t[i-1]-k]+k*f[i]-k*(k-1)/2*d[i]);
                    ans=max(ans,dp[i][j]);
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

下午继续练练思维

你可能感兴趣的:(动态规划,动态规划,c++,算法,背包)