1.方程
给出非负整数n,统计不定方程x+y^2+z^3=n,的非负整数解(x,y,z)的数量。
令k=n-z^3;
则k最多有10^6个值
x+y^2=k
y的取值个数有sqrt(k)+1个
累加y
#include<fstream> #include<cmath> using namespace std; ifstream cin("equation.in"); ofstream cout("equation.out"); long long n,k,ans; long long x,y,z; int main() { cin>>n; ans=0; z=0; while ((z*z*z)<=n) { k=n-z*z*z; y=(int)sqrt((double)k)+1; ans+=y; z++; } cout<<ans; return 0; }
2.方程式
模拟,字符串处理
注意结果是0的时候
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var s,left,right,temp:string;
tot,num,t,tmp,i:longint;
flag:boolean;
ans:double;
begin
assign(input,'equationagain.in');reset(input);
assign(output,'equationagain.out');rewrite(output);
readln(s);
t:=pos('=',s);
left:=copy(s,1,t-1);
right:=copy(s,t+1,length(s)-t);
t:=length(left);
for i:=1 to t do
begin
if left[i] in ['0'..'9'] then temp:=temp+left[i]
else
begin
if left[i]='x' then
begin
if temp='' then tmp:=1 else val(temp,tmp);
if flag then tmp:=-tmp;
flag:=false;
inc(tot,tmp);
temp:='';
end
else
begin
val(temp,tmp);
if flag then tmp:=-tmp;
flag:=false;
inc(num,tmp);
temp:='';
end;
end;
if left[i]='-' then flag:=true;
if (i=t)and(left[i] in ['0'..'9']) then
begin
val(temp,tmp);
if flag then tmp:=-tmp;
flag:=false;
inc(num,tmp);
temp:='';
end;
end;
t:=length(right);
tot:=-tot;
for i:=1 to t do
begin
if right[i] in ['0'..'9'] then temp:=temp+right[i]
else
begin
if right[i]='x' then
begin
if temp='' then tmp:=1 else val(temp,tmp);
if flag then tmp:=-tmp;
flag:=false;
inc(tot,tmp);
temp:='';
end
else
begin
val(temp,tmp);
if not flag then tmp:=-tmp;
inc(num,tmp);
flag:=false;
temp:='';
end;
end;
if right[i]='-' then flag:=true;
if (i=t)and(right[i] in ['0'..'9']) then
begin
val(temp,tmp);
if not flag then tmp:=-tmp;
flag:=false;
inc(num,tmp);
temp:='';
end;
end;
if num=0 then ans:=0 else
ans:=num/tot;
writeln(ans:0:3);
close(input);close(output);
end.
3.MUTI
貌似是数学题,我开始也一直向数学解法上想。
其实是一个经典的完全无限背满包
f[i]=sigma(f[i-a[j]);
#include<fstream> using namespace std; ifstream cin("muti.in"); ofstream cout("muti.out"); int n,c; int a[110]; int f[100010]; int main() { cin>>n>>c; for (int i=1;i<=n;i++) cin>>a[i]; f[0]=1; for (int i=1;i<=n;i++) { for (int j=a[i];j<=c;j++) { f[j]+=f[j-a[i]]; f[j]%=999983; } } cout<<f[c]<<endl; return 0; }
4.交错匹配
DP
f[i][j]=max{f[i][j-1],f[i-1][j]}
找到距离i最近的a[s]和b[k]相等f[i][j]>?=f[s-1][k-1];
#include<fstream> using namespace std; ifstream cin("cross.in"); ofstream cout("cross.out"); int m,n; int a[1010],b[1010],s[32768]; int k,f[1010][1010]; int main(void) { int i,j; cin>>n>>m; for (i=1;i<=n;i++) cin>>a[i]; for (i=1;i<=m;i++) cin>>b[i]; for (i=0;i<=32767;i++) s[i]=10000; for (i=1;i<=n;i++) { k=0; for (j=1;j<=m;j++) { if (a[i]==b[j]) {k=j;} if (a[i]!=b[j]) if ((s[b[j]]<i)&&(k>0)) f[i][j]>?=(f[s[b[j]]-1][k-1]+2); f[i][j]>?=f[i][j-1]; f[i][j]>?=f[i-1][j]; } s[a[i]]=i; } cout<<f[n][m]<<endl; return 0; }