DP的序--Codeforces956E. Wardrobe

$n \leq 10000$个盒子,有高度,高度总和$\leq 10000$,盒子有重要的和不重要的,问最多有多少重要盒子的底端在区间$[L,R]$。

这是个入门级的DP,但需要一点胆量MD这题能放DIV1E。。

放盒子顺序:不重要的,重要的,然后乱放。不重要的可以无脑放,但重要的需要一定的顺序。。

其实重要的盒子按从大到小的顺序无脑叠就行了。。为啥。。

如果是在$L$处的话,那大的堆下面可以把小的送上去;如果是在$L,R$间,那顺序无所谓;如果是在$R$处,先大再小肯定不优,但我们是在01背包,因此大的那个完全可以丢掉。。

有个小问题,底端算答案有点难,不如把整个问题倒过来用顶端算贡献。

为啥这题都不会啊有没有大佬来拯救一下QAQ

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 //#include<math.h>
 5 //#include<queue>
 6 //#include<vector>
 7 #include<algorithm>
 8 #include<iostream>
 9 //#include<assert.h>
10 using namespace std;
11 
12 int n,L,R,H;
13 #define maxn 10011
14 int f[maxn],a[maxn],la=0,b[maxn],lb=0,c[maxn];
15 bool cmp(const int &a,const int &b) {return a>b;}
16 
17 int main()
18 {
19     scanf("%d%d%d",&n,&L,&R);
20     for (int i=1;i<=n;i++) scanf("%d",&c[i]),H+=c[i];
21     L^=R^=L^=R; L=H-L; R=H-R;
22     for (int i=1,x;i<=n;i++) {scanf("%d",&x); if (x) b[++lb]=c[i]; else a[++la]=c[i];}
23     
24     for (int i=1;i<=H;i++) f[i]=-0x3f3f3f3f; f[0]=0;
25     for (int i=1;i<=la;i++)
26         for (int j=H;j>=a[i];j--)
27             f[j]=max(f[j],f[j-a[i]]);
28     
29     sort(b+1,b+1+lb,cmp);
30     for (int i=1;i<=lb;i++)
31         for (int j=H;j>=b[i];j--)
32             f[j]=max(f[j],f[j-b[i]]+(L<=j && j<=R));
33 //    for (int i=0;i<=H;i++) cout<<f[i]<<' ';cout<<endl;
34     
35     int ans=0;
36     for (int i=0;i<=H;i++) ans=max(ans,f[i]);
37     printf("%d\n",ans);
38     return 0;
39 }
View Code

 

posted @ 2018-04-11 20:50  Blue233333  阅读(350)  评论(0)    收藏  举报