jzoj4245-er【dp,贪心】
正題
題目大意
nnn個武器(n≤2n\leq2n≤2),mmm個符文
符文1:直接改變一個武器的攻擊力(最多一個)
符文2:增加一個武器的攻擊力
符文3:使一個人的武器攻擊力翻若干倍
求武器攻擊力乘積最大,輸出答案的自然對數。
解題思路
首先log(ab)=log(a)+log(b)log(ab)=log(a)+log(b)log(ab)=log(a)+log(b)
然后乘積的就不管,最后答案加上就好了,我們只考慮前兩種
n=1n=1n=1時直接暴力枚舉選多少加攻擊的。
n=2n=2n=2時我們考慮dpdpdp。首先我們肯定選大的,主要考慮哪個加在哪個上面。
fi,jf_{i,j}fi,j?表示前iii個符文,第一個武器攻擊力為jjj時的武器威力乘積。我們維護一下前綴和就可以計算第二個武器的攻擊力
若加在第一個符文上fi,j=min{fi?1,j?addi+addi?(sumi?j)}f_{i,j}=min\{f_{i-1,j-add_i}+add_i*(sum_i-j)\}fi,j?=min{fi?1,j?addi??+addi??(sumi??j)}
若加在第二個符文上fi,j=min{fi?1,j+addi?j}f_{i,j}=min\{f_{i-1,j}+add_i*j\}fi,j?=min{fi?1,j?+addi??j}
然后轉移。
之后暴力枚舉加的符文選幾個,其他都選乘的。
對于符文1,直接處理333次
codecodecode
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int N=110; int n,m,k,add[N],sum[N],cnt1,cnt2,mul[N]; int fff,f[N][N*2000],maxs[N],a1,a2; double ans,summ[N]; bool cmp(int x,int y) {return x>y;} int main() {//freopen("data.in","r",stdin);//freopen("data.out","w",stdout);scanf("%d%d%d",&n,&m,&k);scanf("%d",&a1);if(n==2) scanf("%d",&a2);for(int i=1;i<=m;i++){int x,t;scanf("%d%d",&t,&x);if(t==1) fff=x;if(t==2) add[++cnt1]=x;if(t==3) mul[++cnt2]=x;}sort(add+1,add+1+cnt1,cmp);sort(mul+1,mul+1+cnt2,cmp);sum[0]=a1+a2;for(int i=1;i<=k;i++){summ[i]=summ[i-1]+log(mul[i]);sum[i]=sum[i-1]+add[i];}if(n==1){for(int i=0;i<=k;i++){ans=max(ans,log(sum[min(i,cnt1)])+summ[min(k-i,cnt2)]);if(i!=k&&fff)ans=max(ans,log(sum[min(i,cnt1)])+summ[min(k-i-1,cnt2)]);}printf("%.3lf\n",ans);return 0;}memset(f,0xcf,sizeof(f));f[0][a1]=a1*a2;for(int i=0;i<=cnt1;i++){for(int j=a1;j<=sum[i];j++){f[i+1][j]=max(f[i][j]+add[i+1]*j,f[i+1][j]);f[i+1][j+add[i+1]]=max(f[i][j]+add[i+1]*(sum[i]-j),f[i+1][j+add[i+1]]);maxs[i]=max(maxs[i],f[i][j]);}}for(int u=0;u<=k;u++){int mu=min(k-u,cnt2);ans=max(ans,log(maxs[min(u,cnt1)])+summ[mu]);}if(fff){k--;sum[0]=fff+a2;for(int i=1;i<=k;i++)sum[i]=sum[i-1]+add[i];memset(f,0xcf,sizeof(f));memset(maxs,0,sizeof(maxs));f[0][fff]=fff*a2;for(int i=0;i<=k;i++){for(int j=fff;j<=sum[i];j++){f[i+1][j]=max(f[i][j]+add[i+1]*j,f[i+1][j]);f[i+1][j+add[i+1]]=max(f[i][j]+add[i+1]*(sum[i]-j),f[i+1][j+add[i+1]]);maxs[i]=max(maxs[i],f[i][j]);}}for(int u=0;u<=k;u++){int mu=k-u;ans=max(ans,log(maxs[u])+summ[mu]);}sum[0]=a1+fff;for(int i=1;i<=k;i++)sum[i]=sum[i-1]+add[i];memset(f,0xcf,sizeof(f));memset(maxs,0,sizeof(maxs));f[0][a1]=a1*fff;for(int i=0;i<=k;i++){for(int j=a1;j<=sum[i];j++){f[i+1][j]=max(f[i][j]+add[i+1]*j,f[i+1][j]);f[i+1][j+add[i+1]]=max(f[i][j]+add[i+1]*(sum[i]-j),f[i+1][j+add[i+1]]);maxs[i]=max(maxs[i],f[i][j]);}}for(int u=0;u<=k;u++){int mu=k-u;ans=max(ans,log(maxs[u])+summ[mu]);}}printf("%.3lf",ans); }總結
以上是生活随笔為你收集整理的jzoj4245-er【dp,贪心】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内置锂电池 + 数字胎压检测:小米米家充
- 下一篇: 欢乐纪中某B组赛【2019.1.29】