zoukankan      html  css  js  c++  java
  • Gift

    【问题描述】

    人生赢家老王在网上认识了一个妹纸,然后妹纸的生日到了,为了表示自己的心
    意,他决定送她礼物。可是她喜爱的东西特别多,然而他的钱数有限,因此他想
    知道当他花一定钱数后剩余钱数无法再购买任何一件剩余物品(每种物品他最多
    买一个)时有多少种方案,两种方案不同,当且仅当两种方案中至少有一件品不
    同,可是由于他忙着准备泡下一个妹纸(chi),因此麻烦聪明的你帮帮忙。

    【输入格式】

    输入第一行 n 和 m,n 表示妹纸喜欢的礼物数目,m 表示现有的钱数,第二行 n
    个数,表示 n 个物品的价格。

    【输出格式】

    输出一行一个数表示方案数目,答案对 1000000007 取模。

    【样例输入 1】
    gift.in
    6 25
    8 9 8 7 16 5

    【样例输出 1】
    gift.out
    15

    【数据范围】
    30%的数据: 0<=n<=100 0<=m<=500
    100% 的数据:0<=n<=1000 0<=m<=1000
    注意:所有物品价格均小于 m

    【题解】
    算法:动态规划
    30%的数据:爆搜+剪枝或DP,DP是三维的…..
    100%的数据:从大到小排一遍序,枚举取到了第i个物品f[j]表示这时剩余j元的方案数.
    取第i个物品:f[j]+=f[j-a[i]],若i取的话,i+1…n一定要被取到,那么剩余的钱在<=m-a[i+1] ,>m-a[i]的范围内时就可以更新答案.

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define ll long long
    #define re register
    #define il inline
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=1005,mod=1000000007;
    bool vis[N];
    int a[N],v[N][N],w[N];
    il int gi()
    {  
      re int x=0;
      re short int t=1;
      re char ch=getchar();
      while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    int main()
    {
        freopen("gift.in","r",stdin);
        freopen("gift.out","w",stdout);
        int n,m,ans=0;
        n=gi();m=gi();
        fp(i,1,n) a[i]=gi();
        sort(a+1,a+1+n);
        fp(i,1,n) w[i]=w[i-1]+a[i];
        fp(i,1,n)
        {
          fp(k,0,a[i])
          {
            if(vis[k]==0) continue;
            fq(j,m,a[i])
            {
                v[j][k]+=v[j-a[i]][k];
                v[j][k]%=mod;
            }
        }
            if(w[i-1]<=m) v[w[i-1]][a[i]]++,vis[a[i]]=1;
        }
        fp(i,0,m)
          fp(j,0,m)
            if(m-i<j) ans=(ans+v[i][j])%mod;
        printf("%d
    ",ans);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    node代码打包为 exe文件---端口进程关闭demo
    java 中几种常用数据结构
    Java 多线程编程
    【java排序】 归并排序算法、堆排序算法
    【java排序】 选择排序,插入排序,希尔算法
    【java排序】冒泡排序、快速排序
    springMVC执行流程及原理
    Java反射机制详解
    【Java并发编程】:并发新特性—信号量Semaphore
    【Java并发编程】:并发新特性—障碍器CyclicBarrier
  • 原文地址:https://www.cnblogs.com/yanshannan/p/7375730.html
Copyright © 2011-2022 走看看