[LOJ2753] 接雨滴

Description

(n) 根柱子,可以按任意顺序放置形成一个二维图形,一个二维图形可以用来接若干单位面积的水。给定 (n le 500) 根柱子的高度 (h_i le 50),求所有可能的水量。

Solution

解法比较神仙

首先将所有柱子从高到低排序,很显然我们只会从高到低填入(当然也可能放弃一些柱子),较短的那些柱子如果没用完也可以不考虑

维护某个状态能接住的水量其实非常困难,我们考虑维护水量和柱子高度的总和

(f[i][j]) 表示从左到右填了 (i) 个空位(注意有些空位可能暂时不放柱子),是否能拼成 (j) 体积的水量和柱子高度的总和

考虑从大到小枚举所有柱子 (i),再从左向右枚举所有空位 (j),从 ((i-1,j-1))((i,j-1)) 转移过来

std::bitset 优化即可

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 505;
const int M = 30005;

bitset <M> f[N],ans;
int n,a[N],sum;

signed main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) sum+=a[i];
    sort(a+1,a+n+1,greater<int>());
    f[1][a[1]]=1;
    for(int i=2;i<=n;i++)
    {
        for(int j=i;j<=n;j++) f[j]|=f[j-1]<<a[i];
        ans|=f[n];
    }
    for(int i=sum;i<M;i++) if(ans[i]) cout<<i-sum<<" ";
    system("pause");
}
原文地址:https://www.cnblogs.com/mollnn/p/13822645.html