• 【HIHOCODER 1601】 最大得分(01背包)


    描述


    小Hi和小Ho在玩一个游戏。给定一个数组A=[A1, A2, ... AN],小Hi可以指定M个不同的值S1,S2, S3 ... SM,这样他的总得分是 ΣSi × count(Si)。(count(Si)是数组中与Si相等的元素的个数)。
    为了增加难度,小Ho要求小Hi选择的S1..SM其中任意两个Si和Sj都满足|Si-Sj| > 1。
    你能帮助小Hi算出他最大得分是多少吗?

    输入


    第一行包含两个整数N和M。
    第二行包含N个整数A1, A2, ... AN。
    对于30%的数据,1 ≤ M ≤ N ≤ 10 =
    对于100%的数据,1 ≤ M ≤ N ≤ 1000 1 ≤ Ai ≤ 100000

    输出


    最大得分

    样例输入

    5 2  
    1 2 1 2 3
    

    样例输出

    5
    

    题解


    把每个数抽象为物品,拥有两个属性(数字和出现次数),通过值排序,(a_i)(a_{i-2})必然不冲突(距离>=2)
    (dp[i][j])为考虑到第i个,选择了j个的最大得分
    转移方程看代码吧

    #include <vector>
    #include <queue>
    #include <cstdio>
    #include <complex>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define inf 1000000000
    #define PI acos(-1)
    #define bug puts("here")
    #define REP(i,x,n) for(int i=x;i<=n;i++)
    #define DEP(i,n,x) for(int i=n;i>=x;i--)
    #define mem(a,x) memset(a,x,sizeof(a))
    typedef unsigned long long ull;
    using namespace std;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void Out(int a){
        if(a<0) putchar('-'),a=-a;
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=1000+10;
    ll a[N],vis[N*N],dp[N][N];
    struct node{
        int a,v;
    }b[N];
    int main()
    {
    	int n=read(),m=read();
    	ll v=0;
    	REP(i,1,n){
            a[i]=read();vis[a[i]]++;
            v=max(v,a[i]);
    	}
    	int tot=0;
    	REP(i,1,v) if(vis[i]) b[++tot]=node{i,vis[i]};
    	REP(i,1,tot){
            REP(j,1,m){
                if(abs(b[i].a-b[i-1].a)>1||i==1)
                     dp[i][j]=max(dp[i-1][j-1]+b[i].a*b[i].v,dp[i-1][j]);
                else dp[i][j]=max(dp[i-2][j-1]+b[i].a*b[i].v,dp[i-1][j]);
            }
    	}
    	printf("%lld
    ",dp[tot][m]);
    	return 0;
    }
    
  • 相关阅读:
    Linux 常见命令使用
    Spring Cloud学习03--OpenFeign基本使用
    Spring Cloud学习02--Ribbon基本使用
    Spring Cloud学习01--Eureka基本使用
    两个都不可对角化的矩阵判断相似
    利用相似转化研究对象
    分段函数的应用
    0820. Short Encoding of Words (M)
    0637. Average of Levels in Binary Tree (E)
    0160. Intersection of Two Linked Lists (E)
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/7624307.html
Copyright © 2020-2023  润新知