zoukankan      html  css  js  c++  java
  • UVA 12563 Jin Ge Jin Qu hao DP

      题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4008

      题目描述: 一共n首歌儿, 要求在t时间唱尽可能多的歌儿, 相同的歌儿的数量下总时长尽可能的长  

      解题思路: 设dp[i] 为正好唱i秒时唱的最多的歌儿的数量, 只有当i正好等于t[j]或者dp[i-t[j]]>=1 的时候才转移(因为i是正好唱了多少秒)

      代码: 

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <map>
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    
    const int maxn = 1e5;
    using namespace std;
    
    int dp[maxn]; // dp(i, j) 表示前 i 首歌儿正好唱 j s
    int t[100];
    
    int main() {
        int T;
        scanf( "%d", &T );
        for( int c = 1; c <= T; c++ ) {
            int n;
            int tot;
            scanf( "%d%d", &n, &tot );
            for( int i = 1; i <= n; i++ ) {
                scanf( "%d", &t[i] );
            }
            tot--;
            memset(dp, 0, sizeof(dp) );
            int res = 0;
            for( int i = 1; i <= n; i++ ) {
                for( int j = tot; j >= t[i]; j-- ) {
    //                if( i == 2 && j == 99 ) {
    //                    cout << dp[1][30] << endl;
    //                    
    //                }
                    if( dp[j-t[i]] >= 1 || j == t[i] ) {
                        dp[j] = max( dp[j], dp[j-t[i]]+1 );
                        res = max( res, dp[j] );
                    }
                }
            }
            int i;
            for(i = tot; dp[i] != res; i--);
            if(res == 0)
                printf("Case %d: %d %d
    ", c, 1, 678);
            else
                printf("Case %d: %d %d
    ", c, 1 + res, i + 678);
        }
        return 0;
    }
    View Code

      思考: 一开始设计的状态是前 i 首歌儿 j 秒内唱的最多的数量, 后来发现这个只能把歌儿的数量求出来, 很难求最长时间, 然后我想既然是要求最长时间, 那我就改成前i 首歌儿 j 秒正好唱完的最多的数量, 发现状态没有办法转移, 因为dp[i][j] 没办法转移到 dp[k][j-t[i]] k是之前唱过的那首歌儿, 那么这样我就不关心前i首歌儿, 只关心正好唱了多少秒, 运用滚动数组就可以了......自己还是没办法将状态和题目的已知条件很好的联系起来......还是得经常做......

       生日快乐

  • 相关阅读:
    Wannafly挑战赛14 F.细胞
    D 勤奋的杨老师(二)(最小割)
    三分算法求最值
    初识最大流
    初识数据结构
    决策型DP
    哈希表
    【BZOJ】1878: [SDOI2009]HH的项链 (主席树)
    【HDU】1520 Anniversary party(树形dp)
    【UVa】1606 Amphiphilic Carbon Molecules(计算几何)
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7289867.html
Copyright © 2011-2022 走看看