2021-10-13 T2 intersect(正难则反)
T2 intersect
题目描述
游乐园内有这样一个项目:扔出 \(N\) 根木棒,猜这些木棒之间会有多少个交点。
形式化地,我们可以假设木棒的长度近似为无穷,木棒可以互相平行,但是不存在木棒相
互重合或者三条及以上木棒交于同一点的情况。
小 D 想要知道,如果扔出 \(N\) 根木棒,是否有可能出现总交点数为 \(M\) 的情况。
本题多组询问。
数据范围及约定
对于前 \(20\%\) 的数据,\(N\leq 5, M\leq 20\);
对于前 \(50\%\) 的数据,\(N\leq 10, M\leq 100\);
对于前 \(80\%\) 的数据,\(N\leq 50, M\leq 2500, Q\leq 10\);
对于 \(100\%\) 的数据,\(N\leq 500, 0\leq M\leq 10^5, Q\leq 10^5\)。
题目分析
对于前 \(20\%\) 的数据,注意到 \(N\) 不超过 \(5\),打表即可通过。
对于前 \(50\%\) 的数据,\(N\) 不超过 \(10\),考虑到可以枚举每一组相互平行的直线数,暴搜即可通过,时间复杂度 \(O(n! + q)\)。
void dfs(int cur,int cro)
{
if(cur == 11) return ;
for(int i = 1;i <= cur + 1;i++)
{
cnt[i]++;
int tmp = 0;
for(int j = 1;j <= cur + 1;j++)
if(i != j) tmp += cnt[j];
if(cro+tmp > 100)
{
cnt[i]--;
continue;
}
flag[cur+1][cro+tmp] = 1;
dfs(cur+1,cro+tmp);
cnt[i]--;
}
}
dfs(0,0);
scanf("%d",&q);
while(q--)
{
int n,m;
scanf("%d%d",&n,&m);
printf("%d\n",flag[n][m]);
}
return 0;
对于前 \(80\%\) 的数据,考虑 DP,状态很好设计,设 \(f_{i,j}\) 表示 \(i\) 条直线有 \(j\) 个交点是否可行。考虑转移,枚举每组相互平行的直线数量 \(k\),则有转移方程 \(f_{i,j} = \cup_{k=1}^{i} f_{i-k,j-(i-k)\times k}\) ,初始状态 \(f_{0,0} = 1\),时间复杂度 \(O(n^4+q)\)。
f[0][0] = true;
for(int i = 1;i <= 50;i++)
for(int j = 0;j <= i * (i - 1) / 2;j++)
for(int k = 1;k <= i;k++)
if(j-(i-k)*k >= 0) f[i][j] |= f[i-k][j-(i-k)*k];
while(q--)
{
int n,m;
scanf("%d%d",&n,&m);
printf("%d\n",f[n][m]);
}
return 0;
对于 \(100\%\)的数据,正难则反,考虑当前的方案与两两相交的方案相差的木棍数量。设 \(g_i\) 表示与全满方案差 \(i\) 个交点所需要的木棍数。考虑转移,枚举相差的交点个数为 \(i\),再枚举当前组内的木棍数量 \(j\),则多差的交点个数为 \(j\times (j-1)/2\),则可根据以上性质得出转移方程 \(g_i = min_{i=1}^{N}(j+g_{i-j\times (j-1)/2})\) 。则对于方案 \(n\) 和 \(m\),成立需满足当且仅当 \(g_{n\times (n-1)/2-m}\leq n\),注意特判掉超出全满情况。预处理时枚举的复杂度为 \(O(n^3)\),转移的复杂度为 \(O(1)\),则总复杂度为 \(O(n^3+q)\)。
memset(g,0x3f,sizeof(g));
g[0] = 0;
for(int i = 0;i <= 500 * 499 / 2;i++)
for(int j = 1;j <= 500;j++)
if(i - j * (j - 1) / 2 >= 0) g[i] = min(g[i],j + g[i-j*(j-1)/2]);
while(q--)
{
scanf("%d%d",&n,&m);
if(m > n * (n - 1) / 2)
{
printf("0\n");
continue;
}
if(g[n * (n - 1) / 2 - m] <= n) printf("1\n");
else printf("0\n");
}
return 0;

浙公网安备 33010602011771号