1025 选菜
#include<cstdio> #include<algorithm> #include<cmath> int n,k; int v[101],t,x; double z; int dp[101][10100],bd=0; struct C{ int p,d,num,bi; C(){bi=0;} }arr[101]; int main(){ scanf("%d%d%lf",&n,&k,&z);x=floor(z*100); for(int i=1;i<=n;i++){scanf("%lf",&z);arr[i].p=floor(z*100);} for(int i=1;i<=n;i++){scanf("%d",&t);arr[i].d=t;} for(int i=1;i<=n;i++){scanf("%d",&t);arr[i].num=t;if(!v[t]){v[t]=1;}} for(int i=1;i<=k;i++){ scanf("%d",&t); for(int j=1;j<=n;j++) if(arr[j].num==t){ arr[j].bi=1; bd+=arr[j].d; x-=arr[j].p; break; } } for(int i=1,k;i<=n;i++){ for(k=1;k<=n;k++)if(arr[k].num==i)break; for(int j=0;j<=x;j++)dp[i][j]=dp[i-1][j]; if(k>n||arr[k].bi==1)continue; for(int j=0;j<=x;j++){ if(j>arr[k].p && dp[i-1][j-arr[k].p]+arr[k].d>dp[i][j]){ dp[i][j]=dp[i-1][j-arr[k].p]+arr[k].d; } } } printf("%d\n",dp[n][x]+bd); return 0; } /* 挑出必点的,剩下的取最优:0-1背包模板 */
1102 采药
#include<cstdio> int t,m; int dp[1010],ti,vi; int main(){ scanf("%d%d",&t,&m); for(int i=1;i<=m;i++){ scanf("%d%d",&ti,&vi); for(int j=t;j>=0;j--) if(j>=ti) dp[j]=(dp[j]>dp[j-ti]+vi?dp[j]:dp[j-ti]+vi); } printf("%d\n",dp[t]); return 0; } /*心情不爽,A了道水题*/
#include<cstdio> #include<cmath> int n,M; long long ans,t[100010],a[100010]; void meg_sort(int l,int r){ if(l+1==r){if(a[l]>0)ans++;return ;} int m=l+(r-l)/2,i=l,j=m,ap=l; meg_sort(l,m);meg_sort(m,r); while(i<m||j<r){ if(j>=r||(i<m&&a[i]>=a[j])){t[ap++]=a[i++];} else {t[ap++]=a[j++];ans+=m-i;} } for(i=l;i<r;i++) a[i]=t[i]; } int main(){ scanf("%d%d",&n,&M); for(int i=1;i<=n;i++){ scanf("%d",a+i); a[i]+=a[i-1]-M; } meg_sort(1,n+1); printf("%lld\n",ans); return 0; } /* 人这一辈子本来就会遇到很多神秘的现象... 原题大意:给出一排红球序列,给你一个白球,然后去击打,可以击打一个,也可以击打一串, 但是要求打中的红球号码平均值必须比白球大; 据此可以把每个球号都减白球号,得到新红球号码 再用a[i]表示前i个新红球的号码和,若a[l]-a[r]可击,则a[r]>a[l](这个卡了很久) 于是在看看数据10^5瞬间就是O(NlgN)的算法:归并排序 若a[i]<a[j]则统计逆序对 */