UVA 1393 - Highways(数论+DP)
题目链接 https://cn.vjudge.net/problem/UVA-1393
【题意】
有一个n行m列的点阵(1<=n,m<=300)一共有多少条非水平非竖直的线穿过其中的两个点?
【思路】
递推,设 为 个方块对应的答案,那么
最后的这个x是最下面最右面的那个点所做贡献,那么这个 应该是多少呢,应该是 中 的整数对的个数减去之前已经被计算过的整数对个数,之前就被计算过的整数对一定是规模缩小1倍后仍然存在的整数对个数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=330;
int gcd(int a,int b){
if(0==b) return a;
return gcd(b,a%b);
}
ll dp[maxn][maxn];
ll ans[maxn][maxn];
int main(){
for(int i=1;i<maxn;++i){
for(int j=1;j<maxn;++j){
dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+(gcd(i,j)==1?1:0);
}
}
for(int i=1;i<maxn;++i){
for(int j=1;j<maxn;++j){
ans[i][j]=ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1]+dp[i][j]-dp[i/2][j/2];
}
}
int n,m;
while(scanf("%d%d",&n,&m)==2){
if(0==n && 0==m) break;
printf("%lld\n",ans[n-1][m-1]*2);
}
return 0;
}

浙公网安备 33010602011771号