关闭

poj 1276 Cash Machine

108人阅读 评论(0) 收藏 举报

题目是多重背包问题

按传统的DP三重循环,时间复杂度太大,一直TLE

背包问题九讲中有个好办法,就是把多重背包编程01背包,边的过程中最个优化,使复杂度降低(具体见背包问题九讲)

 

 

//转来的代码

#include <iostream>

using namespace std;

int a[15][2];
int dp[120001];
int value[1001];

int main()
{
int cash, n;
while (cin >> cash >> n)
{
int i;
int k = 0;
for (i = 0; i < n; ++i)
{
cin >> a[i][0] >> a[i][1];
int j = 1;
while (j <= a[i][0])
{
value[k++] = a[i][1] * j;
a[i][0] -= j;
j *= 2;
}
if (a[i][0] > 0)
value[k++] = a[i][1] * a[i][0];
}
memset(dp,0,sizeof(dp));
for (i = 0; i < k; ++i)
for (int j = cash; j >= 0; --j)
{
if (j - value[i] >= 0)
dp[j] = dp[j] > dp[j-value[i]] + value[i] ? dp[j] : dp[j-value[i]] + value[i];
}
cout << dp[cash] << endl;
}
return 0;
}

还有种方法是在DP中加入强剪枝,减小搜索范围,自己试了好久一直TLE 悲剧啊。

 

#include <iostream>
#include
<cstdio>
#include
<cmath>
#include
<algorithm>
using namespace std;


struct node
{

    
int num;
    
int value;

}
a[15];




bool dp[100001];
int cash,N;


int main ()
{
    
int i,j,k;
    
while(scanf("%d%d",&cash,&N)!=EOF)
    
{


        memset(dp,
0,sizeof(dp));
        
for(i=1;i<=N;i++)
            scanf(
"%d%d",&a[i].num,&a[i].value);
        
if (cash==0||N==0)
        
{
            printf(
"0/n");
            
continue;
        }


        
int max=0;
        dp[
0]=true;
        
for(i=1;i<=N;i++)
        
{
            
if(a[i].value>cash)
                
continue;
            
for(j=max;j>=0;j--)
            
{
                
if(dp[j]==true)
                
for(k=1;k<=a[i].num;k++)
                
{
                

                    
{
                        
int temp=j+k*a[i].value;
                        
if(temp>cash)
                            
break;
                        
if(temp>max)
                        
{
                            max
=temp;
                            
                        }

                        dp[temp]
=true;
                    }

                }

            }

        }

        printf(
"%d/n",max);

    }

    
return 0;
}

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1418次
    • 积分:55
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章存档