poj 1742

这是一个简单的多重背包问题 , 但关键在于这个题目没有必要记录最优值 , 只需要记录能不能到达。
下面贴出两个代码:

代码1:
#include
#include
using namespace std;

int xy[110][2] ;
bool gh[100010];
int n , m;

int main()
{
      while(scanf("%d %d" , &n , &m) && n)
      {
           
           
            memset(gh , 0 , sizeof(gh));
            gh[0] = 1;
            int i , j;
            int maxsum = 0;
            for(i = 0; i < n; i++)
                  scanf("%d" , &xy[i][0]);
            for(i = 0; i < n; i++)
                  scanf("%d" , &xy[i][1]);
           
           
            for(i = 0; i < n; i++)
            {
                 
                  for(j = m; j >= xy[i][0] ; j--)  //运用了背包的思想 , 拆物
                  {
                        if(gh[j] == 0) 
                        {
                              int k = j/xy[i][0];
                    if(k <= xy[i][1])   k = k*xy[i][0];
                    else k =xy[i][1]*xy[i][0];
                    if(gh[j-k])
                        gh[j] = 1;

                        }
                  }
                 
            }
            int sum = 0;
            for(i = m; i >= 1; i--)
                  if(!gh[i])
                  {
                        sum += 1;
                  }
            cout<<m-sum<<endl;
      }
      return 0;
}

代码2:
#include
#include
using namespace std;

int xy[110][2] ;
int gh[100010];
int n , m;

int main()
{
      while(scanf("%d %d" , &n , &m) && n)
      {
           
           
            memset(gh , 0 , sizeof(gh));
            gh[0] = 1;
            int i , j;
            int maxsum = 0;
            for(i = 0; i < n; i++)
                  scanf("%d" , &xy[i][0]);
            for(i = 0; i < n; i++)
                  scanf("%d" , &xy[i][1]);
           
           
            for(i = 0; i < n; i++)
            {
                 
                  for(j = m; j >= xy[i][0] ; j--)  //运用了背包的思想 , 拆物
                  {
                        if(gh[j] == 0) 
                        {
                              int k = j/xy[i][0];
                    if(k <= xy[i][1] && gh[j-k*xy[i][0]])
                        gh[j] = 1;
                    else if(k > xy[i][1] && gh[j-xy[i][1]*xy[i][0]])
                        gh[j] = 1;

                        }
                  }
                 
            }
            int sum = 0;
            for(i = m; i >= 1; i--)
                  if(!gh[i])
                  {
                        sum += 1;
                  }
            cout<<m-sum<<endl;
      }
      return 0;
}

这两个代码的结果是 , 代码1 AC  , 代码2 TEL

代码1 和代码2 的区别是 , 程序中红色的代码段 。
就是有两个运算 , 代码1 是单独拿出来运行 , 代码2 是放在数组下标中运行 , 这就造成了两个程序的结果不一样 。

以后一些简单的运算 , 拿出来单独运算。

这里还有另外一种方法
#include <iostream>
#include <string.h>
using namespace std;

int xy[110][2] ;
int gh[100010][2];
int n , m;

int main()
{
      while(scanf("%d %d" , &n , &m) && n)
      {
            memset(gh , 0 , sizeof(gh));
            gh[0][1] = 1;
            int i , j;
            int maxsum = 0;

            for(i = 0; i < n; i++)
                  scanf("%d" , &xy[i][0]);
            for(i = 0; i < n; i++)
                  scanf("%d" , &xy[i][1]);
                 
            for(i = 0; i < n; i++)
            {
                  for(j = 0; j <= m; j++)  gh[j][0] = 0;

                  for(j = xy[i][0]; j <= m ; j++)  //运用了背包的思想 , 拆物
                  {
                        if(gh[j][1] == 0)
                        {
                              int num=j-xy[i][0];
                              if(num >= 0)
                                    if(gh[num][1]==1 && gh[num][0]< xy[i][1]) 
                                          gh[j][1]=1, gh[j][0]=gh[num][0]+1;
                        }
                  }
           
            }
            int sum = 0;
            for(i = m; i >= 1; i--)
                  if(!gh[i][1])
                  {
                        sum += 1;
                  }
            cout<<m-sum<<endl;
      }
      return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值