标签:lower tran long strong 1.0 fine 模拟 hit 级别
emmm...作为本蒟蒻的实际意义上的第一篇博客,当然要认真写写才不反正也没什么人看
T1 题意简述:求二元不定方程的正整数解组数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
ll n,blk,cnt,head[2001],siz[2001],dp[2001][2001];
struct uio{
ll nxt,to,val;
}edge[4001];
void add(ll x,ll y,ll z)
{
edge[++cnt].nxt=head[x];
edge[cnt].to=y;
edge[cnt].val=z;
head[x]=cnt;
}
void dfs(ll x,ll fa)
{
siz[x]=1;
dp[x][0]=dp[x][1]=0;
for(ll i=head[x];i;i=edge[i].nxt)
{
ll y=edge[i].to;
if(y==fa) continue;
dfs(y,x);
siz[x]+=siz[y];
}
for(ll i=head[x];i;i=edge[i].nxt)
{
ll y=edge[i].to,z=edge[i].val;
if(y==fa) continue;
for(ll j=min(siz[x],blk);j>=0;j--)
for(ll k=0;k<=min(j,siz[y]);k++)
if(dp[x][j-k]!=-1)
{
ll wei=z*(k/*此子树黑点个数*/*(blk-k)/*另一子树黑点个数*/+
(siz[y]-k)/*此子树白点个数*/*(n-blk-(siz[y]-k))/*另一子树白点个数*/);
dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[y][k]+wei);
}
}
}
int main()
{
freopen("coloration.in","r",stdin);
freopen("coloration.out","w",stdout);
scanf("%lld%lld",&n,&blk);
for(ll i=1;i<n;i++)
{
ll u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
memset(dp,-1,sizeof(dp));
dfs(1,0);
printf("%lld\n",dp[1][blk]);
return 0;
}
n,m,k≤100000
解题思路:首先感谢坐在我旁边的erkkierkko大佬教会我这道题。erkkierkko大佬TQL!!!
容易看出,光线改变方向的次数是O(n+m+k)级别的,因此我们可以进行模拟。
把障碍存在set里(边界也要存),每次由光线所在位置及朝向方向+lower_bound即可得出下一障碍位置。
时间复杂度O((n+m+k)logn )。
由于光线必然不会相交 <=== erkkierkko大佬证明得出
因此不必去重,且结束条件仅两种:
1.光线回到起点,且路径上的每个点都只经过一次
2.光线回到起点,且路径上的每个点都经过了两次
对于这两种情况,只需记录是否曾沿反方向经过了起点,若是则将ans/2,否则直接输出ans即可。
代码:尚未码出,稍后补足。(咕咕咕?)
标签:lower tran long strong 1.0 fine 模拟 hit 级别
原文地址:https://www.cnblogs.com/water-radish/p/9315121.html