codefoces 730J

codeforces 730J

题目链接(luogu)https://www.luogu.org/problemnew/show/CF730J
首先讲这道题分析一下。杯子分为倒与不倒,01背包。
确立背包内容:k易得,在众多抉择中选出最佳的决策。
本题有两种思路,一种是用水做dp,一种是用体积做dp,只说第一种(空间更小)。
目的是用k个杯子并让其中的水最多。(t最小)
首先决定为dp_i_j_k,指当前已经判断到i了且选用了j个杯子,其中有k份水.
所以可以推到选或不选
那么dp[i][j][k]=>dp[i-1][j][k]或dp[i-1][j-1][k-bot[i].le]+bot[i].vi)两个决策。
于是递推即可。
可以知道不同水量下的体积。
只用让这体积>=总的水量
所以逆推水量,找到体积合适的时候,记住循环的标记(i)
再用水的体积减去该数即可。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct bos
{
    int le,vi;
};
bool cmp(bos a,bos b)
{
    return a.vi>b.vi;
}
bos bot[105];
int dp[105][10005];
int main()
{
    int n,sum=0;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>bot[i].le;
        sum+=bot[i].le;
    }
    for(int i=1;i<=n;i++)
    {
        cin>>bot[i].vi;
    }
    int diss=0,flag=0;
    sort(bot+1,bot+n+1,cmp);
    for(int i=1;i<=n;i++)   
    {
        diss+=bot[i].vi;
        if(diss>=sum)
        {
            flag=i;
            break;
        }
    }
    memset(dp,0xff,sizeof(dp));
    dp[0][0]=0;
    for(int i=1;i<=n;i++)
        for(int j=i;j>=1;j--)
            for(int k=sum;k>=bot[i].le;k--)
            {
                if(dp[j-1][k-bot[i].le]!=-1)
                    dp[j][k]=max(dp[j][k],dp[j-1][k-bot[i].le]+bot[i].vi);
            }
    int two=0;
    for(int i=sum;i>=0;i--)
    {
        if(dp[flag][i]>=sum)
            {
                two=sum-i;
                break;
            }
    }
    cout<<flag<<" "<<two;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值