zoukankan      html  css  js  c++  java
  • UVa 12563

    背包问题简单使用,利用滚动数组法可以实现,因为题目中还提到在歌曲数目相同的情况下尽可能时间久,这时候就可以引入另一个DP数组tdp记录策略所对应的歌曲时间。
    需要注意的是,tdp的大小关系的定义:

    • dp[j-s[i]]+1> dp[j]时,没有争议,dp(i, j)状态时,应该选择第i首歌曲,tdp应该更新为相应策略的时间
    • dp[j-s[i]]+1== dp[j],争议出现,这时候选择tdp更小的那个策略
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <cmath>
    #include <vector>
    using namespace std;
    
    const int maxn= 55;
    const int maxt= 180*maxn;
    const int GJJ= 678;
    
    int dp[maxt], tdp[maxt];
    int s[maxn];
    
    void Init(int t)
    {
    	for (int i= t; i> 0; --i){
    		dp[i]= s[1]< i ? 1 : 0;
    		tdp[i]= dp[i] ? GJJ+s[1] : GJJ;
    	}
    }
    
    int main()
    {
    	int T, n, t, kase;
    
    	scanf("%d", &T);
    	for (kase= 1; kase<= T; ++kase){
    		scanf("%d %d", &n, &t);
    		for (int i= 1; i<= n; ++i){
    			scanf("%d", s+i);
    		}
    		Init(t);
    
    		for (int i= 2; i<= n; ++i){
    			for (int j= t; j> 0; --j){
    				if (s[i]>= j){
    					continue;
    				}
    				if (dp[j-s[i]]+1> dp[j]){
    					dp[j]= dp[j-s[i]]+1;
    					tdp[j]= tdp[j-s[i]]+s[i];
    				}
    				else if (dp[j-s[i]]+1== dp[j] && tdp[j-s[i]]+s[i]> tdp[j]){
    					tdp[j]= tdp[j-s[i]]+s[i];
    				}
    			}
    		}
    		printf("Case %d: %d %d
    ", kase, dp[t]+1, tdp[t]);		
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    实验一、DOS使用命令实验
    实验三、进程调度模拟程序
    实验四、存储管理
    实验二、作业调度模拟程序
    简单的DOS命令
    结构化方法和面向对象方法的比较
    jstree 取消选中父节点
    T4 模板代码生成
    基于Open XML 导出数据到Excel
    菜单(列存储转为行存储)
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/13775797.html
Copyright © 2011-2022 走看看