福大校赛好像2个月前举办的,在福大OJ上搞了同时的在线比赛,当时做了一下,切了4道题。。。之后把G和J独立完成,现在说一下这两道题
G(FZU 2127)
构建符合条件的三角形个数,先列个方程,发现是就是解三元不定不等式组组,虽说三元方程,但可以穷举某一个变量,进而以时间的代价简化问题复杂度,简化为二元不等式组,画图搞定,一些细节要考虑清楚,不过我是1A。。。代码:
#include <iostream>
#include <cstdio>
using namespace std;
#define ll __int64
int main()
{
int n,a1,a2,b1,b2,c1,c2,i;
while (cin>>n)
{
cin>>a1>>a2>>b1>>b2>>c1>>c2;
int p,q;
p=max(n/3,c1);
q=min(c2,(n-1)/2);
ll zs=0;
for (i=p;i<=q;i++)
{
int x,y,x1,y1,x2,y2;
x=n-2*i;
y=(n-i)/2;
if (x<=y)
{
x1=max(a1,x);
y1=min(a2,y);
if (x1<=y1)
{
x2=max(b1,n-i-y1);
y2=min(b2,n-i-x1);
ll k=y2-x2+1;
if (k>0) zs+=k;
}
}
}
cout<<zs<<endl;
}
return 0;
}
J(fzu 2129)
这题一看挺经典的,标准组合数学推公式问题,推荐
用dp[i] 表示以第i个数为结尾的个数,sum(i)表示以前i个数组成的子序列和
显然有dp[i] = sum[i-1] +1
这道题重点是解决重数问题,这个只在sum[i]中处理就好了
对于a[i] = a[j] i<j 来讲,dp[i] 被 dp[j] 包含
所以遇到重数时 sum[i] = sum[i-1] + dp[i] - dp[k]
附代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#define mod 1000000007
#define N 1000005
#define cl(a) memset(a,0,sizeof(a))
#define ss(a) scanf("%d",&a)
using namespace std;
int dp[N],sum[N],b[N];
int main()
{
int i,n;
while (ss(n)!=EOF)
{
cl(b);
for (i=1;i<=n;i++)
{
int x;
ss(x);
if (!b[x])
{
dp[i]=(sum[i-1]+1)%mod;
sum[i]=(sum[i-1]+dp[i])%mod;
}
else
{
int t=b[x];
dp[i]=(sum[i-1]+1)%mod;
sum[i]=((sum[i-1]+dp[i]-dp[t])%mod+mod)%mod;
}
b[x]=i;
}
printf("%d\n",sum[n]);
}
return 0;
}