Problem #1: 没有兄弟的舞会 928/2446
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
寻找权值和最大和最小的点集,要求点集满足最多只有一对兄弟。
想法一:贪心,枚举每一个节点的子节点(让0的子节点为1),取最大最小值,对于子节点数大于等于2的取次小次大节点的最小最大值,最后加上即可.
const int maxn = 1e5+100;
vector<int>son[maxn];
ll a[maxn];
int n;
bool cmp(int x,int y){return a[x] < a[y];}
void Solve(){
scanf("%d",&n);ll x;
for(int i=0;i<=n;i++) son[i].clear();
son[0].push_back(1);
for(int i=2;i<=n;i++){
scanf("%I64d",&x);
son[x].push_back(i);
}
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++) sort(son[i].begin(),son[i].end(),cmp);
ll MAX = 0,MIN = 0,x1 = LINF, x2 = -LINF;
for(int i=0;i<=n;i++){
int sz = son[i].size();
if(!sz) continue;
MAX += max(a[son[i][sz-1]],0ll);
MIN += min(a[son[i][0]],0ll);
if(sz >= 2){
x2 = max(x2, a[son[i][sz-2]]);
x1 = min(x1, a[son[i][1]]);
}
}
MAX = max(MAX, MAX + x2);
MIN = min(MIN, MIN + x1);
printf("%I64d %I64d\n",MAX, MIN);
}
想法二:树形DP,对于每一个节点,维护已有一队兄弟的状态得到的结果和尚未有一队兄弟的状态得到的结果,取最优值
Problem #2: 序列期望 545/1163
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
经典求期望,枚举上界,对于每一个上界可求一个等差数列,运用num(小于等于h)−num(小于等于h)−num(小于等于h−1)num(小于等于h−1)的数量来得到上界正好是hh的数量
const int maxn = 1e2+100;
ll ksm(ll x,ll n){
ll res = 1ll;
while(n){
if(n&1) res = res * x % mod;
x = x * x % mod;
n /= 2;
}
return res % mod;
}
ll inv(ll n){
return ksm(n, mod-2)%mod;
}
ll l[maxn],r[maxn],cnt[maxn];
ll SUM(ll l, ll r) {
return (l+r) * (r-l+1) / 2 %mod;
}
ll work(ll i, ll x, ll type = 0) {
if(l[i] > x-type) return 0;
return SUM(x - min(x - type,r[i]) + 1, x - l[i] + 1);
}
void Solve(){
int n;scanf("%d",&n);
ll fenmu = 1;
ll up = 0;
for(int i=1;i<=n;i++){
scanf("%I64d %I64d",&l[i],&r[i]);
fenmu = ( fenmu * ( r[i] - l[i] + 1) ) % mod;
up = max( up , r[i] );
}
ll res = 0ll,tem ;
for(ll i = 1; i <= up; i++){
cnt[n+1] = 1;
for(ll j = n ; j >= 1 ; j --) {
cnt[j] = cnt[j+1] * work(j,i) % mod;
}
tem = 1;
for(ll j = 1 ; j <= n ; j ++) {
if(i <= r[j] && i >= l[j]) {
res = res + tem * cnt[j+1] %mod;
res %= mod;
}
tem = tem * work(j,i,1) % mod;
if(!tem) break;
}
}
res = res * inv(fenmu) % mod;
res = (res % mod + mod) % mod;
printf("%I64d\n", res);
}
Problem #3: 带劲的and和 791/2435
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
并查集维护一下连通性就行了,我总感觉数据给小了。