• Steadily Growing Steam


    这个dp以前没见过 确实不会 怎么才能保证两两互不相交呢 在我印象里面没有这样操作过的dp

    考虑换个想法 设dp[i,j,k]表示 前i个 两者差值为j 用了k次加倍 因为下标不能为负 所以整体向右偏移1300

    初始化 dp[0,1300,0]=0 答案 max{dp[n,1300,i]} i属于[0,k]

    转移方程:dp[i,j,k]=max(dp[i-1,j+v[i],k]+w[i],dp[i-1,j-v[i],k]+w[i],dp[i-1,j+2v[i],k-1]+w[i],dp[i-1,j-2v[i],k-1]+w[i])

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    using namespace std;
    const int N=103;
    typedef long long ll;
    ll f[N][3003][N],w[N],v[N];
    int main()
    {
    	memset(f,-0x3f,sizeof f);
    	f[0][1300][0]=0;
    	int n,m;
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    		scanf("%lld%lld",&w[i],&v[i]);
    	for(int i=1;i<=n;i++)
    	for(int j=0;j<=m;j++)
    	for(int k=0;k<=2600;k++)
    	{
    		f[i][k][j]=f[i-1][k][j];
    		if(k>=2*v[i]&&j>=1)
    			f[i][k][j]=max(f[i][k][j],f[i-1][k-2*v[i]][j-1]+w[i]);
    		if(k>=v[i])
    			f[i][k][j]=max(f[i][k][j],f[i-1][k-v[i]][j]+w[i]);
    		if(k+2*v[i]<=2600&&j>=1)
    			f[i][k][j]=max(f[i][k][j],f[i-1][k+2*v[i]][j-1]+w[i]);
    		if(k+v[i]<=2600)
    			f[i][k][j]=max(f[i][k][j],f[i-1][k+v[i]][j]+w[i]);
    	}
    	ll ans=-0x3f3f3f3f;
    	for(int i=0;i<=m;i++)
    		ans=max(ans,f[n][1300][i]);
    	cout<<ans;
    	return 0;
    }
  • 相关阅读:
    谈谈Nullable<T>的类型转换问题
    MiniProfiler使用方法
    捕获变量
    web服务相关的问题或技巧
    对接mysql数据库遇见的一些问题
    委托
    导出到Excel
    斐波那契数列的运算时间
    .net framework摘抄与理解
    sql 语句
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/16176807.html
Copyright © 2020-2023  润新知