A.平方序列
解题思路
- 不会吧、不会吧,这还有人不会~~~
- 差点没做出来,因为不会用windows的计算器;
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5;
/*
7020
====
我连计算器都不会用~~
*/
int main(){
ll f1=2019*2019;
for(int i=2020;;i++){
ll f2=i*i;
ll temp=f2-f1;
ll f3=f2+temp;
double t=sqrt(f3);
if((int)t==t){
// cout<<i<<" "<<t<<endl;
// cout<<f2-f1<<" "<<f3-f1<<endl;
/// cout<<i+t<<endl;
break;
}
}
return 0;
}
B.质数拆分
解题思路
- 典型的01背包问题,但菜到扣脚的我却一股脑的往BFS上钻~
- 用DP[i][j]表示前i个质数组成j的方案数;
- 可以得到状态转移方程:
– dp[i][j]=dp[i-1][j]+dp[i-1][j-num[i]]
代码展示
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5;
/*
背包问题从0的话怎么处理
*/
bool Judge(int x){
if(x<2)return false;
for(int i=2;i*i<=x;i++)
if(x%i==0)return false;
return true;
}
vector<int>num;
ll dp[1000][3000];
int main(){
int k=0;
num.push_back(0);
for(int i=2;i<=2019;i++)
if(Judge(i)){
++k;
num.push_back(i);
}
int ans=0;
int n;
cout<<k<<endl;
cin>>n;
dp[0][0]=1;
for(int i=1;i<=k;i++){
for(int j=0;j<=n;j++){
dp[i][j]=dp[i-1][j];//不选第i见商品
if(j>=num[i])
dp[i][j]+=dp[i-1][j-num[i]];
}
}
cout<<dp[k][n]<<endl;
return 0;
}
C.切割
解题思路
D.求值
解题思路
1.数论
利用公式,详见第十二届-阶乘约数
2.暴力解法
- 两重循环遍历;
- 第一层遍历数x,然后第二层寻找x的因子数。
#include <iostream>
using namespace std;
int main()
{
for (int i = 1; i <= 100000; i ++)
{
int cnt = 0;
for (int j = 1; j <= i; j ++)
if(i % j == 0) cnt ++;
if(cnt == 100)
{
cout << i << endl;
return 0;
}
}
}
~~待补充
总结
- 一定去研究典型的DP问题(记住它们的题型、模拟出它们的过程)
- 尽量找一个测试样例,最好是比较复杂的。(不然的话佘阳天的那题,岂不是血亏)