zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 2287 【POJ Challenge】消失之物

    Description

    ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN。 由于她的疏忽, 第 i 个物品丢失了。 “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” -- 这是经典的问题了。她把答案记为 Count(i, x) ,想要得到所有1 <= i <= N, 1 <= x <= M的 Count(i, x) 表格。

    Input

    第1行:两个整数 N (1 ≤ N ≤ 2 × 103) 和 M (1 ≤ M ≤ 2 × 103),物品的数量和最大的容积。

    第2行: N 个整数 W1, W2, ..., WN, 物品的体积。

    Output

    一个 N × M 的矩阵, Count(i, x) 的末位数字。

    Sample Input

    3 2
    1 1 2

    Sample Output

    11
    11
    21

    HINT

    如果物品3丢失的话,只有一种方法装满容量是2的背包,即选择物品1和物品2。

    Solution

    首先一点,背包物品的转移顺序对答案是没有影响的
    考虑二分,(solve(l,r)) 代表此时用 ([1,l))((r,n]) 的物品将背包处理好了,需
    要求 (iin[l,r]) 的答案
    ([l,r]) 分为两段,如果要处理 ([l,mid]) ,就用 ((mid,r]) 的物品更新当前背包;处理 ((mid,r]) ,就用 ([l,mid]) 的物品去更新当前背包
    (l=r) 时,当前背包就是去掉物品 (l) 的答案了

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=2000+10;
    int n,m,w[MAXN],f[20][MAXN];
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    inline void solve(int dep,int l,int r)
    {
    	if(l==r)
    	{
    		for(register int i=1;i<=m;++i)write(f[dep][i]%10);puts("");
    		return ;
    	}
    	int Mid=(l+r)>>1;
    	for(register int i=0;i<=m;++i)f[dep+1][i]=f[dep][i];
    	for(register int i=Mid+1;i<=r;++i)
    		for(register int j=m;j>=w[i];--j)(f[dep+1][j]+=f[dep+1][j-w[i]])%=10;
    	solve(dep+1,l,Mid);
    	for(register int i=0;i<=m;++i)f[dep+1][i]=f[dep][i];
    	for(register int i=l;i<=Mid;++i)
    		for(register int j=m;j>=w[i];--j)(f[dep+1][j]+=f[dep+1][j-w[i]])%=10;
    	solve(dep+1,Mid+1,r);
    }
    int main()
    {
    	read(n);read(m);
    	for(register int i=1;i<=n;++i)read(w[i]);
    	f[0][0]=1;solve(0,1,n);
    	return 0;
    }
    
  • 相关阅读:
    vi/vim
    Linux相关知识
    Pikachu实验环境搭建
    DVWA-XSS(Reflected)(反射型跨站脚本攻击)
    DVWA-SQL Injection(Blind)(SQL盲注)
    DVWA—File Upload(文件上传)
    DVWA—Command Injection(命令注入)
    DVWA—Command Injection(命令注入)中出现乱码
    DVWA—Brute Force(暴力破解)
    sqli-labs闯关之61-65关
  • 原文地址:https://www.cnblogs.com/hongyj/p/9517519.html
Copyright © 2011-2022 走看看