题目
分析
-
出看这道题嗯,代码量很大
- 打了暴力,却忘了精度问题
- 我们首先要知道一个小知识:log(a*b)=log(a)+log(b)
- 这样乘法就解决了
- 然后就是一个DP,设f[i][j]为用了i个道具,有了价值为j的最大的第二个道具的值
- 转移方程就是
f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]);
f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); - 因为赋值的只有一个,所以我们只需要,枚举就好了
代码
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #define ll long long 7 using namespace std; 8 const int N=110; 9 int jia[N],che[N],sum[N],f[110][N*2000],maxs[N]; 10 double summ[N]; 11 double ans; 12 bool cmp(int a,int b){ 13 return a>b; 14 } 15 int main () 16 { 17 ios::sync_with_stdio(false); 18 int n,m,k; 19 cin>>n>>m>>k; 20 int x=0,y=0; 21 if (n==1) 22 cin>>x; 23 else 24 cin>>x>>y; 25 int cnt1=0,cnt2=0; 26 int fff=0; 27 for (int i=1,b,c;i<=m;i++) 28 { 29 cin>>b>>c; 30 if (b==1) 31 fff=c; 32 if (b==2) 33 jia[++cnt1]=c; 34 if (b==3) 35 che[++cnt2]=c; 36 } 37 sort(jia+1,jia+1+cnt1,cmp); 38 sort(che+1,che+1+cnt2,cmp); 39 sum[0]=x+y; 40 for (int i=1;i<=k;i++) 41 { 42 summ[i]=summ[i-1]+log(che[i]); 43 sum[i]=sum[i-1]+jia[i]; 44 } 45 if (n==1) 46 { 47 for(int i=0;i<=k;i++) 48 { 49 ans=max(ans,log(sum[min(i,cnt1)])+summ[min(k-i,cnt2)]); 50 if(i!=k&&fff) 51 ans=max(ans,log(sum[min(i,cnt1)])+summ[min(k-i-1,cnt2)]); 52 } 53 printf("%.3lf ",ans); 54 return 0; 55 } 56 memset(f,0xcf,sizeof(f)); 57 f[0][x]=x*y; 58 for(int i=0;i<=cnt1;i++) 59 { 60 for(int j=x;j<=sum[i];j++) 61 { 62 f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]); 63 f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); 64 maxs[i]=max(maxs[i],f[i][j]); 65 } 66 } 67 for(int u=0;u<=k;u++) 68 ans=max(ans,log(maxs[min(u,cnt1)])+summ[min(k-u,cnt2)]); 69 if(fff) 70 { 71 k--; 72 sum[0]=fff+y; 73 for(int i=1;i<=k;i++) 74 sum[i]=sum[i-1]+jia[i]; 75 memset(f,0xcf,sizeof(f)); 76 memset(maxs,0,sizeof(maxs)); 77 f[0][fff]=fff*y; 78 for(int i=0;i<=k;i++) 79 { 80 for(int j=fff;j<=sum[i];j++) 81 { 82 f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]); 83 f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); 84 maxs[i]=max(maxs[i],f[i][j]); 85 } 86 } 87 for(int u=0;u<=k;u++) 88 ans=max(ans,log(maxs[u])+summ[k-u]); 89 sum[0]=x+fff; 90 for(int i=1;i<=k;i++) 91 sum[i]=sum[i-1]+jia[i]; 92 memset(f,0xcf,sizeof(f)); 93 memset(maxs,0,sizeof(maxs)); 94 f[0][x]=x*fff; 95 for(int i=0;i<=k;i++) 96 { 97 for(int j=x;j<=sum[i];j++) 98 { 99 f[i+1][j]=max(f[i][j]+jia[i+1]*j,f[i+1][j]); 100 f[i+1][j+jia[i+1]]=max(f[i][j]+jia[i+1]*(sum[i]-j),f[i+1][j+jia[i+1]]); 101 maxs[i]=max(maxs[i],f[i][j]); 102 } 103 } 104 for(int u=0;u<=k;u++) 105 ans=max(ans,log(maxs[u])+summ[k-u]); 106 } 107 printf("%.3lf",ans); 108 }