洛谷 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;
}