20160317 CodeVS 1025 选菜,1102 采药,3324 新斯诺克

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了道水题*/

3324 新斯诺克

#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]则统计逆序对

*/



你可能感兴趣的:(算法,dp,动态规划,归并排序,背包DP)