// 题目链接: https://nanti.jisuanke.com/t/28204
1 //动态规划,重复利用子问题的最优,来求解当前最优问题
2 #include <iostream>
3 #include <cstdio>
4 #include <cstring>
5 #include <string>
6 #include <algorithm>
7 #include <vector>
8 #include <queue>
9 using namespace std;
10 typedef long long ll;
11 int t;
12 const int N=1600;
13 int s[N];
14 int dp[N];//在第i层下楼时从一楼到i楼共生气的最小值
15 const int inf=0x3f3f3f3f;
16 int main()
17 {
18 scanf("%d",&t);
19 while(t--)
20 {
21 int n;
22 scanf("%d",&n);
23 int sum=0;
24 for(int i=1;i<=n;i++)
25 {
26 scanf("%d",&s[i]);
27 sum+=s[i];
28 }
29 dp[0]=0;
30 int ski;
31 for(int i=1;i<=n;i++)
32 {
33 sum-=s[i];//这一层下楼,那么此时前面的都会下,sum为高层人数。
34 ski=0;
35 dp[i]=inf;
36 for(int j=i-1;j>=0;j--)
37 {
38 dp[i]=min(dp[i],dp[j]+ski+sum);//
39 ski+=(i-j)*s[j];//该在j层下,却在i 层才下楼
40 }
41 }
42 //因为dp[i]为i层下楼的。。,因此用不下楼来更新
43 printf("%d\n",dp[n]);
44 }
45 return 0;
46 }
D. Lift Problems
1 //在喜欢的里面取mid个,在不喜欢的里面取s-mid个。
2 #include <iostream>
3 #include <cstdio>
4 #include <cstring>
5 #include <algorithm>
6 using namespace std;
7 int T;
8 const int N=1e5+9;
9 int t[N],p[N];
10 int main()
11 {
12 int i,j,l,r,mid,maxx,n,s,f,k;
13 scanf("%d",&T);
14 while(T--)
15 {
16 scanf("%d%d%d",&n,&s,&f);
17 for( i=0;i<n;i++)
18 scanf("%d",&t[i]);
19 sort(t,t+f);//要分别排序
20 //因为分成喜欢与不喜欢
21 sort(t+f,t+n);
22 scanf("%d",&k);
23 for(i=0;i<k;i++)
24 scanf("%d",&p[i]);
25 l=max(0,s-(n-f));//下界
26 r=min(s,f);//上界
27 while(l<=r)//因为上界可能取到
28 {
29 mid=(l+r)>>1;
30 maxx=t[n-(s-mid)-1];//不喜欢的不取的最大值
31 for(i=0;i<k-f-(s-mid);i++)//把P数组小的加到不喜欢的不取的小的部分
32 maxx=max(maxx,p[i]+t[k-1-(s-mid)-i]);
33 for(j=0;j<mid&&t[f-1-j]+(k-mid+j<0?0:p[k-mid+j])>=maxx;j++);
34 //喜欢中所取的所有值都要大于不喜欢中不取的最大值
35 if(j==mid)//这个mid是可以的
36 l=mid+1;
37 else
38 r=mid-1;
39 }
40 printf("%d\n",l-1);
41
42 }
43 return 0;
44 }