完全背包問題__模數運算

來源:互聯網
上載者:User
題目大意

做法

定義有數量限制的叫大件,其餘是小件。
考慮最小的那個體積v1。
如果連v1都是大件,DP容易解決。
不然的話,考慮在模v1意義下進行,最終要湊出的S必定是S%v1。
問題在於,湊出S%v1不一定能湊出S。
實際上,如果能湊出x,x+v1也能湊出。
因此考慮求出每個模意義下能湊出的最小數便可以每次判定能否湊出。
不過還有大件限制困擾我們。我們設f[i,j]表示用了i個大件,湊出在模意義下結果為j的最小數是多少,這個DP方程有後效性。
如果按照用了幾個大件分層,處理一層後可以推到下一層(加一個大件)相當於賦個初值,接下來一層內轉移圖形成環的形狀(對於同一個小件),找到環中最小值,指向它的邊可以刪去,便可以破環為鏈,進行簡單遞推了。

#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;typedef long long ll;const int maxn=50+10,maxd=10000+10;ll f[maxd][maxn],g[maxd];bool bz[maxd];int a[maxn];int i,j,k,l,r,id,c,t,n,m;ll v;int main(){    freopen("bag.in","r",stdin);freopen("bag.out","w",stdout);    scanf("%d%d",&n,&m);    fo(i,1,n) scanf("%d",&a[i]);    scanf("%d%d",&l,&c);    sort(a+1,a+n+1);    fo(i,1,n){        if (a[i]>=l) break;        t=i;    }    fo(i,0,a[1])        fo(j,0,c)            f[i][j]=1000000000000000005;    fo(i,0,a[1]) g[i]=1000000000000000005;    f[0][0]=0;    g[0]=0;    fo(j,0,c){        if (j){            fd(k,n,t+1){                fo(i,0,a[1]-1)                    f[i][j]=min(f[i][j],f[((i-a[k])%a[1]+a[1])%a[1]][j-1]+(ll)a[k]);            }        }        fd(k,t,2){            fo(i,0,a[1]-1) bz[i]=0;            fo(i,0,a[1]-1)                if (!bz[i]){                    r=i;id=i;                    while (!bz[r]){                        bz[r]=1;                        if (f[r][j]<f[id][j]) id=r;                        r=(r+a[k])%a[1];                    }                    r=id;                    while ((r+a[k])%a[1]!=id){                        f[(r+a[k])%a[1]][j]=min(f[(r+a[k])%a[1]][j],f[r][j]+(ll)a[k]);                        r=(r+a[k])%a[1];                    }                }        }        fo(i,0,a[1]-1)            g[i]=min(g[i],f[i][j]);    }    while (m--){        scanf("%lld",&v);        if (g[v%a[1]]<=v) printf("Yes\n");else printf("No\n");    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.