关于贪心思想与DP的结合的几点认识

LYD loves codeforces since there are many Russian contests. In an contest lasting for T minutes there are n problems, and for the ith problem you can get aiditipoints, where ai indicates the initial points, di indicates the points decreased per minute (count from the beginning of the contest), and ti stands for the passed minutes when you solved the problem (count from the begining of the contest).
Now you know LYD can solve the ith problem in ci minutes. He can't perform as a multi-core processor, so he can think of only one problem at a moment. Can you help him get as many points as he can?

Input

The first line contains two integers n,T(0≤n≤2000,0≤T≤5000).
The second line contains n integers a1,a2,..,an(0<ai≤6000).
The third line contains n integers d1,d2,..,dn(0<di≤50).
The forth line contains n integers c1,c2,..,cn(0<ci≤400).

Output

Output an integer in a single line, indicating the maximum points LYD can get.

Example Input
3 10
100 200 250
5 6 7
2 4 10
Example Output

254


这道题是处理花费时间与递减时间的除数,然后根据除数排序,然后就是裸的背包。根据除数排序我能理解,就是有的题目你越早做损失的分数就越少,然后我们就按这个顺序来做题,但这样做题肯定是不对的,为什么呢?因为每道题的初始分值是不一样的,有的排完序之后虽然靠后,也就意味着可能在有限的时间里不会被选到,但这道题的初始分却很高,选择这道题的的分数比按顺序得到的分数要高,那么这就出问题了。所以这就需要我们重新来考虑一下这道题的做法了。然后我想了很久也没想明白,排不排序似乎对DP过程没什么影响啊!!!可能是我做题做的太少思考不到位的缘故吧,以后留着思考。


【tyvj1048】田忌赛马

2013年11月23日 2,098 2

题目描述

        中国古代的历史故事“田忌赛马”是为大家所熟知的。话说齐王和田忌又要赛马了,他们各派出N匹马,每场比赛,输的一方将要给赢的一方200两黄金,如果是平局的话,双方都不必拿出钱。现在每匹马的速度值是固定而且已知的,而齐王出马也不管田忌的出马顺序。请问田忌该如何安排自己的马去对抗齐王的马,才能赢取最多的钱?

输入

第一行为一个正整数n  (n  < =  1000)  ,表示双方马的数量。 第二行有N个整数表示田忌的马的速度。 第三行的N个整数为齐王的马的速度。

输出

仅有一行,为田忌赛马可能赢得的最多的钱,结果有可能为负。

样例输入

3 92 83 71 95 87 74

样例输出

200

我之所以把这两道题归结在一起,是觉得这都是用了贪心来优化DP

1.思路
不妨用贪心思想来分析一下问题。因为田忌掌握有比赛的“主动权”,他总是根据齐王所出的马来分配自己的马,所以这里不妨认为齐王的出马顺序是按马的速度从高到低出的。由这样的假设,我们归纳出如下贪心策略:
如果田忌剩下的马中最强的马都赢不了齐王剩下的最强的马,那么应该用最差的一匹马去输给齐王最强的马。
如果田忌剩下的马中最强的马可以赢齐王剩下的最强的马,那就用这匹马去赢齐王剩下的最强的马。
如果田忌剩下的马中最强的马和齐王剩下的最强的马打平的话,可以选择打平或者用最差的马输掉比赛。
2.反例
光是打平的话,如果齐王马的速度分别是1 2 3,田忌马的速度也是1 2 3,每次选择打平的话,田忌一分钱也得不到,而如果选择先用速度为1的马输给速度为3的马的话,可以赢得200两黄金。
光是输掉的话,如果齐王马的速度分别是1 3,田忌马的速度分别是2 3,田忌一胜一负,仍然一分钱也拿不到。而如果先用速度为3的马去打平的话,可以赢得200两黄金。

3.解决方案
通过上述的三种贪心策略,我们可以发现,如果齐王的马是按速度排序之后,从高到低被派出的话,田忌一定是将他马按速度排序之后,从两头取马去和齐王的马比赛。有了这个信息之后,动态规划的模型也就出来了!

4.DP方程
设f[i,j]表示齐王按从强到弱的顺序出马和田忌进行了i场比赛之后,从“头”取了j匹较强的马,从“尾”取了i-j匹较弱的马,所能够得到的最大盈利。
状态转移方程如下:
F[I,j]=max{f[i-1,j]+c[n-(i-j)+1,i],f[i-1,j-1]+c[j,i]}
其中g[i,j]表示田忌的马和齐王的马分别按照由强到弱的顺序排序之后,田忌的第i匹马和齐王的第j匹马赛跑所能取得的盈利,胜为1,输为-1,平为0。
结果用最大的乘以200即可。

5.解释

为什么F[I,j]=max{f[i-1,j]+c[n-(i-j)+1,i],f[i-1,j-1]+c[j,i]}可以呢?

因为你无论怎么样都是从前或者从后面取马,而F[I,j]=max{f[i-1,j]+c[n-(i-j)+1,i],f[i-1,j-1]+c[j,i]}这个方程把所有可能的贪心情况都表示出来了。


#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int f[3001][3001],a[3001],b[3001],c[3001][3001];
int n,ans=0;
bool gz(int a,int b) {return a>b;}
int main()
{
    cin>>n;
    for(int i=0;i<=n;i++)
       for(int j=0;j<=n;j++)
          f[i][j]=-999999;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)cin>>b[i];
    sort(a+1,a+n+1,gz);
    sort(b+1,b+n+1,gz);
    for(int i=1;i<=n;i++)
       for(int j=1;j<=n;j++)
          if(a[i]>b[j])c[i][j]=1;
          else if(a[i]==b[j])c[i][j]=0;
          else c[i][j]=-1;
    f[0][0]=0;
    for(int i=1;i<=n;i++)
       for(int j=0;j<=i;j++)
          if(j>=1)f[i][j]=max(f[i-1][j]+c[n-(i-j)+1][i],f[i-1][j-1]+c[j][i]);
          else f[i][j]=f[i-1][j]+c[n-(i-j)+1][i];
    for(int i=0;i<=n;i++)
        ans=max(f[n][i],ans);
    cout<<ans*200;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值