洛谷 P7774 [COCI2009-2010#2] KUTEVI(DP:完全背包)

https://www.luogu.com.cn/problem/P7774

题目大意:

给定n个已知角度a[1],a[2],,,a[n];
给定m个需要我们去拼凑的角度b[1],b[2],,,b[m];

数组a中的角度可以使用任意多次,从0开始对数组a中的角度进行加、减运算,
如果数组b中的角度可以被拼凑出来,输出YES,否则输出NO。
输入 #1复制
2 1
30 70
40
输出 #1复制
YES
输入 #2复制
1 1
100
60
输出 #2复制
YES
输入 #3复制
3 2
10 20 30
5 70
输出 #3复制
NO
YES
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL N=200200,M=2002;
LL a[N],b[N];
LL f[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        LL n,m;
        cin>>n>>m;
        for(LL i=1;i<=n;i++)
            cin>>a[i];
        for(LL i=1;i<=m;i++)
            cin>>b[i];
        f[0]=1;//每个角度的初始值都是为0 
        for(LL i=1;i<=n;i++)//n个角度
        {
            for(LL j=0;j<=1000;j++)//最多旋转1000次,直接返回原点(其实这题的n数据范围特别小,j可以开大一点完全没事)
            {
                //|或操作有一个即为有
                if(j>=a[i]) f[j%360]|=f[(j-a[i])%360];//不要后退至<0,后退取模影响最终结果
                f[j%360]|=f[(j+a[i])%360];
            }
        }
        for(LL i=1;i<=m;i++)
        {
            if(f[b[i]]==1) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }
	return 0;
}
posted @ 2022-09-27 20:06  Vijurria  阅读(126)  评论(0编辑  收藏  举报