总结一下这周,实在是太不满意了,效率狗屎低,时间没有安排好。
做回太慢了,看了USACO一两题 又回去想那几题,简直了。。(对了疯山的考试真是丧心病狂 还傻傻的想复习)
随便讲一下题吧(长话短说,懒,我还要复生物呢)。
第一题 Sonya and Problem Wihtout a Legend
其实不难 把严格上升改为不降之后DP就好
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define me(a,x) memset(a,x,sizeof a)
#define cp(a,x) memcpy(a,x,sizeof a)
using namespace std;
typedef long long LL;
struct node{int x,y;}p[2010];
int Cmp(node x1,node x2){return x1.x<x2.x;}
int a[2010],b[2010]; LL f[2010],s[2010];
int main()
{
int T,n,i,j; LL ans;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]),a[i]-=i,p[i].x=a[i],p[i].y=i;
sort(p+1,p+1+n,Cmp);
int al=1; a[p[1].y]=1,b[1]=p[1].x;
for(i=2;i<=n;i++)
{
if(p[i].x!=p[i-1].x)al++;
a[p[i].y]=al,b[al]=p[i].x;
}
me(s,0);
for(i=1;i<=n;i++)
{
for(j=1;j<=al;j++)f[j]=s[j]+abs(b[j]-b[a[i]]);
s[1]=f[1];
for(j=2;j<=al;j++)s[j]=min(s[j-1],f[j]);
}
printf("%I64d\n",s[al]);
}
return 0;
}
第二题是contest hunter上CH round #50的第三题
这道题感觉很厉害 Tree DP的样子
F1[x][i] 表示这个点走到i距离的在他子树下的点的总费用(包括自己子树下的总和)
F2[x][i] 表示这个点走到i距离的在他子树外的点的总费用(包括自己子树下的总和)
G[x]=min(F1[x][]);
F1[x][i]=min(F1[son[x]][i-1]+C[i]+sigma(G[otherson[x]],F2[otherson[x]][i+1]))
F2[x][i]=C[i]+sigma(min(F2[son[x]][i+1],G[son[x]])
大概就是这样 贴代码
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define me(a,x) memset(a,x,sizeof a)
#define cp(a,x) memcpy(a,x,sizeof a)
using namespace std;
typedef long long LL;
const int N=200010,m=20;
struct node{int y,next;}a[N]; int first[N],len;
void ins(int x,int y)
{
a[++len].y=y,a[len].next=first[x],first[x]=len;
}
int n,c[N],phi[N],p[N/5],pl,f1[N][m+2],f2[N][m+2],g[N];
bool b[N];
void getp()
{
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!b[i])phi[i]=i-1,p[++pl]=i;
for(int j=1;j<=pl;j++)
{
if(i*p[j]>n)break; b[i*p[j]]=1;
if(i%p[j]) phi[i*p[j]]=phi[i]*(p[j]-1);
else {phi[i*p[j]]=phi[i]*p[j]; break;}
}
}
}
void dp(int x)
{
int i,k;
if(!first[x])
{
for(i=0;i<=m;i++)f2[x][i]=c[i];
f1[x][0]=g[x]=c[0];
return;
}
for(k=first[x];k;k=a[k].next) dp(a[k].y);
for(i=0;i<=m;i++)
{
int mn=f1[0][0];
f1[x][i]=f2[x][i]=c[i];
for(k=first[x];k;k=a[k].next)
{
int y=a[k].y,t=min(f2[y][i+1],g[y]);
f1[x][i]+=t,f2[x][i]+=t;
if(i) mn=min(mn,f1[y][i-1]-t);
}
if(i)f1[x][i]+=mn;
g[x]=min(g[x],f1[x][i]);
}
}
int main()
{
int i,j;
scanf("%d",&n);
for(i=0;i<n;i++) scanf("%d",&c[i]);
getp();
for(i=2;i<=n;i++) ins(phi[i],i);
me(f1,63),me(f2,63),me(g,63);
dp(1);
printf("%d\n",g[1]);
return 0;
}
第四题他们都不back 那我也不做了。。有点费时间