zoukankan      html  css  js  c++  java
  • $POJ1742 Coins$ 多重背包+贪心

    Vjudge传送门

    $Sol$

    首先发现这是一个多重背包,所以可以用多重背包的一般解法(直接拆分法,二进制拆分法...)

     但事实是会TLE,只能另寻出路

    本题仅关注“可行性”(面值能否拼成)而不是“最优性”,这是一个特殊之处。

    从这里找优化

    在“最优性”的问题中,$f[j]$从$f[j]$或$f[j-a[i]]$中转移而来;而在这样的“可行性”问题中,其实只要$f[j]$可行,我们就可以不用考虑$f[j-a[i]$了,也可以反过来说。

    于是我们可以考虑一种贪心策略,设$used[j]$表示$f[j]$在阶段$i$时为$True$至少要用多少枚第$i$中硬币。

    $f[j]$优先考虑由$f[j]$转移而来,而不是$f[j-a[i]]$,这样就尽量减少了第$i$种硬币的使用数量。

    其实还可以在作一个小优化,就是直接把$used[j]$的值存在$f[j]$中,$f[]$初始为$-1$,意为不能表示。

    $Code$

     1 #include<iostream>
     2 #include<cstdio>
     3 #define Rg register
     4 #define il inline
     5 #define db double
     6 #define ll long long
     7 #define go(i,a,b) for(Rg int i=a;i<=b;i++)
     8 #define yes(i,a,b) for(Rg int i=a;i>=b;i--)
     9 using namespace std;
    10 il int read()
    11 {
    12     int x=0,y=1;char c=getchar();
    13     while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    14     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    15     return x*y;
    16 }
    17 const int N=101;
    18 int n,m,a[N],c[N],f[100001];
    19 ll ans;
    20 il void sol()
    21 {
    22     go(i,1,m)f[i]=-1;
    23     go(i,1,n)
    24         go(j,0,m)
    25     {
    26         if(f[j]>=0)f[j]=c[i];//f[0]=c[i]可以看成是初始化
    27         else if(j>=a[i]&&f[j-a[i]]>0)f[j]=f[j-a[i]]-1;//第i种硬币还有剩余
    28     }
    29     go(i,1,m)if(f[i]>=0)ans++;
    30 }
    31 int main()
    32 {
    33     while(1)
    34     {
    35         n=read(),m=read();ans=0;
    36         if(!n&&!m)break;
    37         go(i,1,n)a[i]=read();go(i,1,n)c[i]=read();
    38         sol();printf("%lld
    ",ans);
    39     }
    40     return 0;
    41 }
    View Code
    光伴随的阴影
  • 相关阅读:
    Ubuntu下的Apache、Mysql、PHP环境搭建
    JS代码引用位置问题-转
    mysql设置定时任务
    js setTimeout函数
    JavaScript向window onload添加加载函数
    写在开博之时
    WPF笔记(一)之初识XMAL
    创建理想的数据库索引
    常见负载均衡算法
    Java设计模式之外观模式
  • 原文地址:https://www.cnblogs.com/forward777/p/10993391.html
Copyright © 2011-2022 走看看