题目链接:https://ac.nowcoder.com/acm/contest/13504/C
思路:
dp[i][j]表示i是否可以表示成为j个平方数的和,状态转移方程为
dp[i][j]=max(dp[i-x][j-1],dp[i][j]),其中x为平方数,如果枚举j会超时,可以使用位运算来优化。
代码:
#include<iostream>
#include<set>
using namespace std;
typedef long long ll;
ll num[1000];
unsigned int dp[1000009];
bool ok[1000009];
int main(){
ll t;
cin>>t;
for(int i=0;i<=500;i++){
num[i]=i*i;
ok[i*i]=1;
}
for(int i=1;i<1000001;i++){
for(int j=1;j<500;j++){
if(i-num[j]<=0) break;
else{
{dp[i]|=(dp[i-num[j]]<<1);}
}
}
if(ok[i]) dp[i]|=1;
}
while(t--){
ll n;
cin>>n;
if(dp[n]&(1<<4)) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
题解可能有错误或者遗漏,大家见谅。