题解 | #简单瞎搞题#

简单瞎搞题

https://ac.nowcoder.com/acm/problem/17193

思路:
因为数据量小,我们可以利用桶取储存每个数最终能不能被选出的方案
那么可以采用dp的方法,f[i][j]中的i表示第i层(输入给的第i行)j表示Σ(xi×xi),我们看f[i][j]是否等于1判断j是否是存在于答案之中的
那么如果我们设l<=k<=r,状态转移方程就是f[i][j]=f[i-1][j+k×k]表示在下一层当中,上一层1的位置再加上k×k就是下一层新的1的位置
但这么做 j 是从1到1e6循环的,很明显会超时
这时候因为采取的是01串,我们可以利用bitset进行优化
因为f[i][j]=f[i-1][j+k×k]
就相当于f[i]|=f[i-1]<<(k×k)(或运算是因为之前的1也要保留,我们是利用桶存储答案,对于每个1的位置都有一个Σ(xi*xi),最后输出最后一层的1的个数即可
AC代码:

#include <bits/stdc++.h>

using namespace std;
bitset<1000010>f[110];//桶存储方案的形式
int main()
{
    int n;
    cin>>n;
    f[0]=1;
    for(int i=1;i<=n;i++){
        int l,r;
        cin>>l>>r;
        for(int k=l;k<=r;k++){
            f[i]|=f[i-1]<<(k*k);//之前的1也要保留,新的1是前面的数加上k*k得到的数的下标的值
        }
    }
    cout<<f[n].count()<<endl;
    return 0;
}
全部评论

相关推荐

2 收藏 评论
分享
牛客网
牛客企业服务