• HDOJ 3732 Ahui Writes Word 多重背包


    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3732

    题目大意:阿辉要记单词,所有单词的长度都不超过10个字符,每个单词都有一定的价值跟复杂性,

    知道每个单词的价值跟复杂性都写下来了,阿辉写单词的总的复杂度不能超过C,要你求阿辉可以得到

    的最大价值。

    解题思路:乍一看本题为一个简单0 1背包问题,但用0 1 背包做的时间复杂度为10^9在一秒中内不可能

    完成,但细看题目后发现Vi和Ci都小于等于10也就是说价值和费用的种类总共只有一百种,只需要统计

    所有价值、费用相同的数目及可以将问题转化为一个多重背包问题。

    源码及注释:

    #include<stdio.h>
    #include<string.h>
    int count[11][11]; //用于统计相同价值和费用的单词的数目
    int dp[10005];
    int max(int a,int b)//求a和b的最大值
    {
    	return a > b ? a : b;
    }
    int main()
    {
    	int n,i,j,v,ci,c;
    	char Str[15];
    	while(scanf("%d%d",&n,&c) != EOF)
    	{
    		memset(count,0,sizeof(count));//将所有种类的数目初始化为0
    		for(i = 0; i < n; i++)
    		{
    			scanf("%s%d%d",Str,&v,&ci);
    			count[v][ci]++;				//统计价值为v费用为ci的单词的数目
    		}
    		memset(dp,0,sizeof(dp));
    		for(i = 0; i < 11; i++)			//i代表价值
    		{
    			for(j = 0; j < 11; j++)		//j代表费用
    			{
    				if(count[i][j] == 0)	//当价值为i费用为j的单词的数量为0的时候则进行下一次循环
    					continue;
    				if(count[i][j] * j >= c)  //完全背包
    				{
    					for(int k = j ; k <= c; k++)
    						dp[k] = max(dp[k],dp[k-j]+i);
    				}
    				else
    				{
    					int l = 1;
    					while(l < count[i][j])  //0 1 背包
    					{
    						for(int k = c; k >= l*j; k--)
    							dp[k] = max(dp[k],dp[k-l*j]+l*i);
    						count[i][j] -= l;
    						l <<= 1;
    					}
    					for(int k = c; k >= count[i][j]*j; k--)
    						dp[k] = max(dp[k],dp[k-count[i][j]*j]+count[i][j]*i);
    				}
    			}
    		}
    		printf("%d\n",dp[c]);
    	}
    	return 0;
    }


     

  • 相关阅读:
    git命令大全
    servlet执行顺序
    github使用教程
    upun使用教程
    jsp标签之<%%>和<%!%>
    spring MVC 详细入门
    jquery之ajax之$.get方法的使用
    jquery之getJSON方法获取中文数据乱码解决方法
    eclipse隐藏菜单栏实现全部酷黑主题
    eclipse快捷键失效的解决办法
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3220837.html
Copyright © 2020-2023  润新知