$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 ",ans); 38 return 0; 39 }