zoukankan      html  css  js  c++  java
  • 子集和问题(应用--换零钱)POJ2229:Sumsets

    我一直在纠结换零钱这一类型的题目,今天好好絮叨一下,可以说他是背包的应用,也可以说他是单纯的dp。暂且称他为dp吧。

    先上一道模板题目。

    sdut2777: 小P的故事——神奇的换零钱

    题目描述

    已知A国经济很落后,他们只有1、2、3元三种面值的硬币,有一天小P要去A国旅行,想换一些零钱,小P很想知道将钱N兑换成硬币有很多种兑法,但是可惜的是他的数学竟然是体育老师教的,所以他不会啊、、、他只好求助于你,你可以帮他解决吗?

    提示:输入数据大于32000组。

    输入

     每行只有一个正整数N,N小于32768。

    输出

     对应每个输入,输出兑换方法数。

    示例输入

    100 
    1500

    示例输出

    884 
    188251

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <math.h>
    #define inf 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    int n,dp[32800],w[4];
    int main()
    {
        w[1]=1;
        w[2]=2;
        w[3]=3;
        memset(dp,0,sizeof(dp));
        dp[0]=1;
        for(int i=1; i<=3; i++)//依次添加每类货币
        {
            for(int j=i; j<=32768; j++)//枚举可使用第i类货币每一种可能的数和
            {
                dp[j]=dp[j]+dp[j-w[i]];// (累计前i-1类货币构成j-w[i]的方式数)
    //dp[j]=dp[j]+dp[j-w[i]]的含义为:使用前i类货币时的货币组成可能可能的数(dp[j])=当使用前i-1类货币时的货币组成可能的数(dp[j])
    //+选择使用一个i类货币+剩余钱数(j-w[i])组成的货币的数目(前i类)---这里有点背包的感觉,所以说他是背包的应用
    } } while(scanf("%d",&n)!=EOF) { printf("%d ",dp[n]); } return 0; }

    POJ2229:

    Description

    Farmer John commanded his cows to search for different sets of numbers that sum to a given number. The cows use only numbers that are an integer power of 2. Here are the possible sets of numbers that sum to 7: 

    1) 1+1+1+1+1+1+1 
    2) 1+1+1+1+1+2 
    3) 1+1+1+2+2 
    4) 1+1+1+4 
    5) 1+2+2+2 
    6) 1+2+4 

    Help FJ count all possible representations for a given integer N (1 <= N <= 1,000,000). 

    Input

    A single line with a single integer, N.

    Output

    The number of ways to represent N as the indicated sum. Due to the potential huge size of this number, print only last 9 digits (in base 10 representation).

    Sample Input

    7

    Sample Output

    6
    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <math.h>
    #define inf 0x3f3f3f3f
    typedef long long ll;
    #define mod 1000000000
    using namespace std;
    int n,w[10010],tt,zan,l,dp[1000010];
    int main()
    {
       tt=0;
       w[tt++]=1;
       for(int i=1;i<=1000;i++)
       {
           zan=pow(2,i);
           if(zan>1000000) break;
           w[tt++]=zan;
       }
       while(scanf("%d",&n)!=EOF)
       {
           memset(dp,0,sizeof(dp));
           dp[0]=1;
           for(int i=0;i<tt;i++)
           {
               if(dp[i]>n) break;
               for(int j=w[i];j<=n;j++)
               {
                   dp[j]=(dp[j]+dp[j-w[i]])%mod;
               }
           }
           printf("%d
    ",dp[n]);
       }
        return 0;
    }
  • 相关阅读:
    随记
    bzoj3551 [ONTAK2010]Peaks加强版
    bzoj2763 [JLOI2011]飞行路线
    bzoj1758 [Wc2010]重建计划
    bzoj1857 [Scoi2010]传送带
    bzoj4519 [Cqoi2016]不同的最小割
    bzoj2229 [Zjoi2011]最小割
    bzoj4129 Haruna’s Breakfast
    bzoj1835 [ZJOI2010] 基站选址
    bzoj2160 拉拉队排练
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/4360947.html
Copyright © 2011-2022 走看看