zoukankan      html  css  js  c++  java
  • POJ-1742Coins

    代码:

    方法一:

    这个是根据完全背包的思路来做,但是加了对个数的限制。

    #include<iostream>
    #include<stdio.h>
    #include<string.h> 
    using namespace std;
    const int maxn = 1e5+10;
    int dp[maxn];
    int sum[maxn];
    int main(){
        int n,m;
        while(cin>>n>>m&&n&&m){
            int a[n+1],c[n+1];
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            for(int i=1;i<=n;i++)
                scanf("%d",&c[i]);
            memset(dp,0,sizeof(dp));
            dp[0]=1;
            int ans = 0;
            for(int i=1;i<=n;i++){
                memset(sum,0,sizeof(sum));
                for(int j=a[i];j<=m;j++){
                    if(!dp[j]&&dp[j-a[i]]&&(sum[j-a[i]]<c[i])){//这里很巧妙
                        dp[j] = 1;//做标记
                        sum[j] = sum[j-a[i]]+1;//计数
                        ans++;
                    }
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }

     方法二:

    这里用到二进制的性质

    例如 有11 个2的话,我们依次存进cnt中 1*2 , 2*2,4*2,4*2;

    即11 被分解为 1 2  4  4

    这4个数能任意组合成1~11中的每一个数,利用这一性质就可以把时间复杂度降下来,O(n)->O(logn)

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    const int maxn = 101;
    int cnt[1001];
    int main(){
        int n,m;
        while(cin>>n>>m&&n&&m){
            int a[maxn];
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            int num;
            int len=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&num);
                int m = 1;
                while(m<num){
                    cnt[len++] = m*a[i];
                    num = num-m;
                    m<<=1;
                }
                cnt[len++] = num*a[i];
            }
            bool dp[100000];
            memset(dp,false,sizeof(dp));
            dp[0] = true; 
            for(int i=0;i<len;i++){
                for(int j=m;j>=cnt[i];j--){
                    if(!dp[j])
                        dp[j] = dp[j-cnt[i]];
                }
            }
            int ans = 0;
            for(int i=1;i<=m;i++){
                if(dp[i]) ans++;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    卷积:如何成为一个很厉害的神经网络
    卷积的本质及物理意义(全面理解卷积)
    傅里叶分析之掐死教程(完整版)
    buf.writeUInt16BE()
    buf.writeUInt8()函数详解
    buf.writeUIntBE()函数详解
    buf.writeInt32BE()函数详解
    buf.writeInt16BE()函数详解
    buf.writeInt8()函数详解
    buf.writeDoubleBE()函数详解
  • 原文地址:https://www.cnblogs.com/lusiqi/p/12341384.html
Copyright © 2011-2022 走看看