POJ 1276 Cash Machine 解答

简介: 题目详见: http://poj.org/problem?id=1276这道题与POJ 1014同属一类题, 区别在于POJ 1014的解是求恰好等于容量的情况, 而这道题较为常规, 同时这道题的数据较大, 套用我在博客http://blog.

题目详见: http://poj.org/problem?id=1276

这道题与POJ 1014同属一类题, 区别在于POJ 1014的解是求恰好等于容量的情况, 而这道题较为常规, 同时这道题的数据较大, 套用我在博客http://blog.csdn.net/hfut_jf/article/details/18190521里写的程序会出现Time Limit Exceeded错误, 必须加以优化, 先贴出原先的程序, 在与最后AC的代码比较, 主要看代码如何改进:

改进前代码(会出现Time Limit Exceeded错误):

#include <iostream>
using namespace std;
const int n=1001;
int main(int argc, char * argv[])
{
    int cash=0, N=0;
	int num[n]; // 每种面值钞票张数
	int d[n]; // 每种钞票对应面值
	int v[100001]; // 背包容量 
	int w[100]; // 压缩用数组

    memset(num, 0, sizeof(num));
    memset(d, 0, sizeof(d));
    while(true){
        // 初始化
        memset(v, 0, sizeof(v));
        
        cin>>cash>>N;
        for(int i=0;i<N;++i){
			cin>>num[i]>>d[i];
		}
		int k=0; // 记录压缩后替代物品数 
		// 二进制压缩
		for(int i=0;i<N;++i){
            int t=1;
            while(num[i]>0){
                if(num[i]>t){
                    num[i]-=t;
                    w[k++]=t*d[i];
                    t*=2;
                }else{
                    w[k++]=num[i]*d[i];
                    num[i]=0;      
                }        
            }
        }
        
        // 执行动态规划算法
        for(int i=0;i<k;++i){
            for(int j=cash;j>=w[i];--j){  
                if(v[j]<v[j-w[i]]+w[i])
                    v[j]=v[j-w[i]]+w[i];
            }
        }
        cout<<v[cash]<<endl; 
    }
    return 0;   
}
改进后代码(已AC):

#include <iostream>
using namespace std;
int main(int argc, char * argv[])
{
    int cash=0, N=0;
	int num[1001];
	int d[1001];
	int v[100001];
    while(cin>>cash>>N){
        memset(v, 0, sizeof(v)); 
        for(int i=0;i<N;++i){
			cin>>num[i]>>d[i];
		    int w=0,t=1;
            while(num[i]>0){
                if(num[i]>t){
                    num[i]-=t;
                    w=t*d[i];
                    t*=2;
                }else{
                    w=num[i]*d[i];
                    num[i]=0;      
                }
                for(int j=cash;j>=w;--j){  
                    if(v[j]<v[j-w]+w)
                        v[j]=v[j-w]+w;
                }        
            } 
        }
        cout<<v[cash]<<endl; 
    }
    return 0;   
}
主要改进:

在一种币值钞票输入后即进行二进制压缩和动态规划计算, 减少了循环次数及所需存储空间.

目录
相关文章
|
6月前
|
Java
hdu-1016-Prime Ring Problem
hdu-1016-Prime Ring Problem
28 0
|
测试技术
HDU-1847,Good Luck in CET-4 Everybody!(巴什博弈)
HDU-1847,Good Luck in CET-4 Everybody!(巴什博弈)
ZOJ - Summer 2018 - Contest 1 by SBconscious - Problems - 1001: Saber
ZOJ - Summer 2018 - Contest 1 by SBconscious - Problems - 1001: Saber
94 0
HDOJ(HDU) 2309 ICPC Score Totalizer Software(求平均值)
HDOJ(HDU) 2309 ICPC Score Totalizer Software(求平均值)
99 0
POJ 2390 Bank Interest
POJ 2390 Bank Interest
103 0
|
人工智能 机器学习/深度学习
POJ 2390 Bank Interest
Problem Description Farmer John made a profit last year! He would like to invest it well but wonders how much money he will make.
818 0