Summer Training #12 Div.2 I(DP)

题目链接  Gym 101028J

题意:男猪脚在森林中穿行,依次经过n个商店,每个商店出售vi能量,他能够从每个商店中补充一定能量,能量数值为vi能够整除的最大2次方的次幂,并且要求他从商店购买的能量数值(vi)必须为递增的顺序,问最多能够补充多少能量?

题解:DP

代码(写的非常丑)

#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
#include<map>
using namespace std;
#define N 105
int shop[N],d[N][N][2],power[N],en[N],rt,power2[N],ans;
int find2(int v){
    int k=0;
    while(!(v%2)){
        k++;
        v/=2;
    }
    return k;

}
int main(){
    freopen("C:/Users/fuliujun/Desktop/input.txt","r",stdin);
    freopen("C:/Users/fuliujun/Desktop/output.txt","w",stdout);
    int T,i,n,j;
    scanf("%d",&T);
    map<int,int>e;
    while(T--){
        e.clear();
        scanf("%d",&n);
        ans=0;
        for(i=1;i<=n;i++)
            {scanf("%d",&shop[i]);
             power[i]=find2(shop[i]);
            }
        memset(d,0,sizeof(d));
        en[1]=shop[1];
        e.insert(pair<int, int>(shop[1],1));
        power2[1]=power[1];
        rt=1;
        int flag=1;
        for(i=2;i<=n;i++){
            flag=1;
            for(j=1;j<=rt;j++)
                if(shop[i]==en[j]){flag=0;break;}
            if(flag){
                en[++rt]=shop[i];
                power2[rt]=power[i];
               e.insert(pair<int, int>(shop[i],j));

            }
        }
        int flagnew[N];
        memset(flagnew,0,sizeof(flagnew));
        for(i=1;i<=rt;i++)d[0][i][0]=en[i];
       for(i=1;i<=n;i++)
       for(j=1;j<=rt;j++){
            if(j==1){
                for(int z=1;z<=rt;z++){
                        d[i][z][0]=d[i-1][z][0];
                        d[i][z][1]=d[i-1][z][1];
                }
            }
            int te=e[shop[i]];
            if(!flagnew[te]){
                d[i][te][1]+=power2[te];
                flagnew[te]=1;
            }
            if(d[i][j][0]<shop[i]){
                d[i][te][1]=max(d[i][j][1]+power2[te],d[i][te][1]);
            }

       }
       for(i=1;i<=rt;i++){
            if(d[n][i][1]>ans){ans=d[n][i][1];}
       }

        printf("%d\n",ans);

    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
View Code

 重新写了一份代码

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int find2(int k){
    int temp=0;
    while(k%2==0){
        temp++;
        k/=2;
    }
    return temp;
}
int main(){
    int i,j,T,n,a[105],b[105],f[105];
    scanf("%d",&T);
    while(T--){
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=find2(a[i]);
        f[i]=b[i];
    }
    for(i=2;i<=n;i++)
    for(j=1;j<i;j++){
        if(a[j]<a[i])f[i]=max(f[j]+b[i],f[i]);
    }
    printf("%d\n",*max_element(f+1,f+n+1));
    }
    return 0;
}
View Code

 

posted @ 2016-07-25 11:25  flowing_water  阅读(136)  评论(0)    收藏  举报