C. Alyona and the Tree
dfs。看看哪些节点需要删去,删掉它为根的子树即可。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100010;
vector<int> sons[maxn];
vector<ll> ew[maxn];
ll vw[maxn];
int ans = 0;
void dfs(int u,ll MAXdist,bool flag){
int sz = sons[u].size();
for(int i=0;i<sz;i++){
int v = sons[u][i];
ll newMax = MAXdist + ew[u][i];
if(MAXdist<0){
newMax = ew[u][i];
}
bool newFlag = 0;
if(flag || newMax > vw[v]){
ans++;
newFlag = 1;
}
dfs(v,newMax,flag || newFlag);
}
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
scanf("%I64d",&vw[i]);
}
for(int i=1;i<n;i++){
int u;
ll ww;
int v=i+1;
scanf("%d%I64d",&u,&ww);
sons[u].push_back(v);
ew[u].push_back(ww);
}
dfs(1,-1,0);
cout<<ans<<endl;
return 0;
}
D. Alyona and Strings
进行2次dp,第一次求出以每个位置结尾的最长公共子串;第二次状态为
dp(i,j,k)
,即到位置
i
,
#include <bits/stdc++.h>
using namespace std;
#define ll long long
char a[1010];
char b[1010];
int num[1010][1010];
int n,m,k;
void LCS(){
int i,j;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(a[i-1]==b[j-1]){
num[i][j]=num[i-1][j-1]+1;
}
}
}
}
int dp[1010][1010][15];
int main(){
cin>>n>>m>>k;
scanf("%s",a);
scanf("%s",b);
LCS();
int ans = 0;
for(int kk=1;kk<=k;kk++){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j][kk] = max(dp[i][j][kk],dp[i-num[i][j]][j-num[i][j]][kk-1] + num[i][j]);
dp[i][j][kk] = max(dp[i][j][kk],dp[i-1][j][kk]);
dp[i][j][kk] = max(dp[i][j][kk],dp[i][j-1][kk]);
dp[i][j][kk] = max(dp[i][j][kk],dp[i-1][j-1][kk]);
if(dp[i][j][kk] >ans){
ans = dp[i][j][kk];
}
}
}
}
for(int i=1;i<=k;i++){
ans = max(ans,dp[n][m][i]);
}
cout<<ans<<endl;
return 0;
}
E. Alyona and Triangles
找出
具体做法是,首先求凸包(注意凸包边上出现的点不能漏),最大三角形一定出现在凸包的点上。然后,枚举第一个点,按顺序枚举第二个点,第三个点随着第二个点的移动单调,利用这个性质在
O(n2)
的时间内得到最大三角形。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
typedef double TYPE;
struct POLY{
int n;
TYPE *x;
TYPE *y;
POLY():n(0),x(NULL),y(NULL){};
POLY(int _n,const TYPE *_x,const TYPE * _y){
n = _n;
x = new TYPE[n+1];
memcpy(x,_x,n*sizeof(TYPE));
x[n] = _x[0];
y = new TYPE[n+1];
memcpy(y,_y,n*sizeof(TYPE));
y[n] = _y[0];
}
}poly;
struct POINT{
TYPE x;
TYPE y;
POINT():x(0),y(0){
}
POINT(TYPE _x,TYPE _y):x(_x),y(_y){
}
POINT operator-(POINT other){
return POINT(x-other.x,y-other.y);
}
POINT operator+(POINT other){
return POINT(x+other.x,y+other.y);
}
};
TYPE Cross(const POINT &a,const POINT &b,const POINT &o){
return (a.x-o.x)*(b.y-o.y) - (b.x-o.x)*(a.y-o.y);
}
TYPE Distance(const POINT &a, const POINT &b){
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
POLY ConvexHull(const POINT *Set, int n){
POINT *points = new POINT[n];
memcpy(points, Set,n*sizeof(POINT));
TYPE *X = new TYPE[n];
TYPE *Y = new TYPE[n];
int i,j,k = 0, top = 2;
for(i = 1;i<n;i++){
if((points[i].y<points[k].y) ||
((points[i].y == points[k].y) &&
(points[i].x<points[k].x))){
k = i;
}
}
swap(points[0],points[k]);
for(i = 1;i<n-1;i++){
k=i;
for(j = i+1;j<n;j++){
if( (Cross(points[j],points[k],points[0])>0) ||
((Cross(points[j],points[k],points[0]) == 0) &&
(Distance(points[0],points[j])<Distance(points[0],points[k])))){
k = j;
}
}
swap(points[i],points[k]);
}
X[0] = points[0].x; Y[0] = points[0].y;
X[1] = points[1].x; Y[1] = points[1].y;
X[2] = points[2].x; Y[2] = points[2].y;
for(i = 3;i<n;i++){
while(Cross(points[i],POINT(X[top],Y[top]),POINT(X[top-1],Y[top-1]))>=0){
top--;
}
++top;
X[top] = points[i].x;
Y[top] = points[i].y;
}
delete[] points;
POLY poly(++top,X,Y);
delete[] X;
delete[] Y;
return poly;
}
POINT pts[5555];
int main(){
int n,s;
cin>>n>>s;
for(int i=0;i<n;i++){
scanf("%lf %lf",&pts[i].x,&pts[i].y);
}
poly = ConvexHull(pts , n);
n=poly.n;
int a[3];
for(int i=0;i<n;i++){
pts[i] = POINT(poly.x[i],poly.y[i]);
}
int j=1,k=0;
double ans=0;
for(int i=0;i<n;i++) {
j=(i+1)%n;
k=(j+1)%n;
while(fabs(Cross(pts[i],pts[j],pts[k]))<fabs(Cross(pts[i],pts[j],pts[(k+1)%n]))) k=(k+1)%n;
while(j!=i&&k!=i) {
if(fabs(Cross(pts[i],pts[j],pts[k])) > ans){
ans = fabs(Cross(pts[i],pts[j],pts[k]));
a[0] = i;
a[1] = j;
a[2] = k;
}
while(fabs(Cross(pts[i],pts[j],pts[k]))<fabs(Cross(pts[i],pts[j],pts[(k+1)%n])))
k=(k+1)%n;
j=(j+1)%n;
}
}
POINT b[3];
b[0] = pts[a[1]] + (pts[a[2]]-pts[a[0]]);
b[1] = pts[a[0]] + (pts[a[2]]-pts[a[1]]);
b[2] = pts[a[0]] + (pts[a[1]]-pts[a[2]]);
for(int i=0;i<3;i++){
cout<<(int)b[i].x<<" "<<(int)b[i].y<<endl;
}
return 0;
return 0;
}