• bzoj-1042 硬币购物


    题意:

    有四种面值的硬币ci,进行tot次购物;

    每次购物每种硬币有di个,问买s元的物品有几种方法;


    题解:

    硬币面值仅仅有四种,能够推測到算法复杂度不会非常大;

    普通的背包无法限制di个这个条件;

    而将di个硬币拆开复杂度无法承受。而且一样难以统计方案;

    所以考虑容斥原理简化问题;

    去掉di的限制,令f[x]表示四种硬币购买x元的物品有几种方法;

    这个f数组能够在O(4*10^5)的复杂度处理。

    然后反向考虑。假设硬币1超过d1个的限制的时候。f[s-c1*(d1+1)]恰好为方案数。

    用总方案减去这些方案数,容斥原理搞一下就好了。

    总感觉自己的容斥有点奇怪。。只是反正乱搞能AC= =;

    似乎要开long long;


    代码:


    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 100001
    using namespace std;
    typedef long long ll;
    int c[4],d[4];
    ll f[N],ans;
    void slove(int now,int val)
    {
    	int k=0;
    	for(int i=0;i<4;i++)
    	{
    		if(now&(1<<i))
    		{
    			k^=1;
    			val-=c[i]*(d[i]+1);
    		}
    	}
    	if(val<0)	return ;
    	ans+=(k?

    -1:1)*f[val]; } int main() { int n,m,i,j,k; for(i=0;i<4;i++) scanf("%d",c+i); scanf("%d",&n); f[0]=1; for(i=0;i<4;i++) { for(j=0;j<N;j++) f[j+c[i]]+=f[j]; } for(i=1;i<=n;i++) { for(j=0;j<4;j++) scanf("%d",d+j); scanf("%d",&m); ans=0; for(j=0;j<16;j++) slove(j,m); printf("%lld ",ans); } return 0; }




  • 相关阅读:
    2019 湖湘杯 Reverse WP
    2017第二届广东省强网杯线上赛--Nonstandard
    2019 上海市大学生网络安全大赛 RE部分WP
    2019 360杯 re wp--Here are some big nums
    MATLAB图像的代数运算
    编辑和剪绳子-头条2019笔试题
    奖品分配-头条2019笔试题
    TrajPreModel
    multiheadattention-torch
    腾讯笔试题-邻值查找
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7079326.html
Copyright © 2020-2023  润新知