zoukankan      html  css  js  c++  java
  • 题解:UESTC1218 Pick The Sticks

    题意:选择长度为ai,价值为vi金条覆盖长度为L的区域,使总价值最大,只要金条重心在区域内即可。

    1<=N<=1000;1<=L<=2000;1<=ai<=2000;1<=vi<=109.

    1~100组数据,10000MS

     

    注意:0/1背包的简单变形:显然最多有2次机会让金条在长度变为一半的情况下价值不变,为了避免0.5的出现,将长度,价值都乘上2DP[i][j][k]表示选择到第i个金条,占用长度为j且已经用了k次机会时最大价值,复杂度O(3*NL).

     

    注意特判只用一根金条时,显然无论金条多长,重心都可在区域内。

     

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int maxn=4400;
    int t,n,l;
    long long a[maxn+5],v[maxn+5]; 
    long long dp[maxn+5][4];
    int main(){
        scanf("%d",&t);
        for (int q=1;q<=t;++q){
            scanf("%d%d",&n,&l);
            for (int i=1;i<=n;++i) {scanf("%lld%lld",&a[i],&v[i]);a[i]=a[i]*2;};
            memset(dp,0,sizeof(dp));
            for (int i=1;i<=n;++i)
                for (int j=2*l;j>=a[i]/2;--j){
                    for (int k=2;k>=1;--k){
                         if (j-a[i]>=0) dp[j][k]=max(dp[j][k],dp[j-a[i]][k]+v[i]);
                         dp[j][k]=max(dp[j][k],dp[j-a[i]/2][k-1]+v[i]);
                    }
                    if (j-a[i]>=0) dp[j][0]=max(dp[j][0],dp[j-a[i]][0]+v[i]); 
                }
            long long ans=0;
            for (int i=1;i<=2*l;++i) ans=max(ans,dp[i][2]);
            for (int i=1;i<=n;++i) ans=max(ans,v[i]);
            printf("Case #%d: %lld
    ",q,ans);
        }
        return 0;
    }
  • 相关阅读:
    (转载)李开复:我在硅谷看到的最前沿科技趋势
    1019. 数字黑洞 (20)
    1018. 锤子剪刀布 (20)
    1017. A除以B (20)
    1016. 部分A+B (15)
    1015. 德才论 (25)
    1013. 数素数 (20)
    1014. 福尔摩斯的约会 (20)
    1012. 数字分类 (20)
    1011. A+B和C (15)
  • 原文地址:https://www.cnblogs.com/terra/p/6986778.html
Copyright © 2011-2022 走看看