NOJ [F] 懒惰的风纪委Elaine 求一堆数能组成多少个数小于等于n

  • [F] 懒惰的风纪委Elaine

  • 时间限制: 1000 ms 内存限制: 65535 K
  • 问题描述
  • Elaine是学园都市中的一个风纪委,每天都会接到命令对某个街道进行检查,并抓捕危险分子。她所在的风纪委支部附近有M条街道。这些街道由北到南并排均匀的分布在一条直线上,每条街道之间的距离都为1。但是众所周知,Elaine是一个很懒很懒的人(-..-说我坏话!!被我看到了!!),她不想一步一步走完所有街道,但好在她的好友Kuso为她制作了大量的传送卷轴。不过,因为Kuso的能力等级太低,他制作的卷轴有严重的缺点,他的卷则只能向南飞一段固定的距离(当然,他预先制作了很多种类的卷轴),而Elaine所在的风纪委支部却在最北边。每一次出去检查,Elain都要使用好几张卷轴。但如果是某些不能传送到的地方,Elaine只能走过去了。不过回来的话,她就可以用自带的传送系统传送到支部的传送点。

    有一天,Elaine想知道,如果她从风纪委支部出发,可以检查那些街道。她手里有N种传送卷轴(1,2,3,,,N),每个卷轴可以传送的距离为Ai,卷轴的数量为Ci。则Elaine靠那些卷轴,可以不走路而直接传送的有哪些街道?

  • 输入
  • 数据有多组输入。每一组数据的第一行有两个数:N,M(0<N<=100,0<M<=1000)。分别表示传送卷轴的种类数和街道数量。在第二行有2N个数,A1,A2,A3...An,C1,C2,C3...Cn (1<=Ai<=100000,1<=Ci<=1000)。数据输入以0 0结束。
  • 输出
  • 每组数据占一行,输出一个数,为Elaine可以传送到的街道总数。
  • 样例输入
  • 3 10
    1 2 4 2 1 1
    2 5
    1 4 2 1
    0 0
  • 样例输出
  • 8
    4
  • 提示
  • 风纪委支部到第一条街道的距离也为1。

     

    http://acm.nbut.cn/Contest/view/id/59/problem/F.xhtml
     
     
    思路  :  多重背包
    #include<stdio.h>
    #include<string.h>
    int c1[1005],c2[1005];
    int a[200],c[200];
    #include<stdio.h>
    #include<string.h>
    int bag[250000+5];
    int val[100000];
    int vis[1001];
    int _01bag(int v,int m)
    {
        int i,j,ans=0;
        memset(bag,0,(v+3)*sizeof(bag[0]));
        for(i=0;i<m;i++)
            for(j=v;j>=val[i];j--)
            {
                if(bag[j]<bag[j-val[i]]+val[i])
                        bag[j]=bag[j-val[i]]+val[i];
                 if(bag[j]<=v) vis[bag[j]]=1;
            }
        for(i=1;i<=v;i++)
            if(vis[i]!=0) ans++;
            return ans;
    
    }
    
    int main()
    {
    	int n,i,j,m;
    	while(1)
    	{
    	    scanf("%d %d",&n,&m);
    	    if(!n&&!m) break;
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d",&a[i]);
    			//a[i]=getval();
    		}
    		for(i=1;i<=n;i++)
    		{
    			scanf("%d",&c[i]);
    			//c[i]=getval();
    		}
            memset(vis,0,sizeof(vis));
            int temp;
            j=0;
            for(i=1;i<=n;i++)
            {
                if(a[i]>m) continue;
                temp=1;
                while(c[i]>temp)
                {
                    val[j++]=temp*a[i];
                    c[i]=c[i]-temp;
                    temp=temp*2;
                }
                val[j++]=c[i]*a[i];
            }
            int ans=_01bag(m,j);
           printf("%d\n",ans);
    
    	}
    	return 0;
    }
    

  • 你可能感兴趣的:(NOJ [F] 懒惰的风纪委Elaine 求一堆数能组成多少个数小于等于n)