1个小时做了2题 然后看到a,d头大 直接无视了
以下内容仅供参考
b题:二分答案 然后check 类似bfs 从每一个没标号的点出发 距离小于mid的都标上号 看看用了几个号码 如果比k多就满足条件 check 复杂度为O(n)
c题:。。像我这种菜鸡最适合做这种题了。。。dp10分钟秒杀
f[i][j]=f[i][j]=max(f[i][j-1]+human[i+j].a*a2+human[i+j].b*b2,f[i-1][j]+human[i+j].a*a1+human[i+j].b*b1);
建议使用滚动数组
b代码:
# include<stdio.h># include<string.h># define EC(a) ((a)*(a))# define mod 10000000int n,k;struct node{ double x,y,z;}web[1001];double s[1001][1001];int vis[1001];bool tank(double define){ memset(vis,0,sizeof(vis)); int i,j,tot=0; int q[1010],front,rear; for(i=1;i<=n;i++) {if(!vis[i]) vis[i]=++tot; front=0,rear=1,q[0]=i; while(front<rear) { for(j=1;j<=n;j++) if(!vis[j]&&s[q[front]][j]<=define) {vis[j]=vis[i];q[rear++]=j; } front++; } } if(tot>=k) return true; return false;}int main(){ scanf("%d%d",&n,&k); double x,y,z; int i,j; for(i=1;i<=n;i++) {scanf("%lf%lf%lf",&x,&y,&z),web[i].x=x,web[i].y=y,web[i].z=z;} for(i=1;i<=n;i++) for(j=1;j<=n;j++) s[i][j]=EC(web[i].x-web[j].x)+EC(web[i].y-web[j].y)+EC(web[i].z-web[j].z); double left=0,right=1,mid; while(left+0.0000001<right) {mid=(left+right)/(2.0); // printf("left:%.7lf right:%.7lf mid:%.7lf\n",left,right,mid); if(!tank(mid)) right=mid-0.0000001; else left=mid; } double ans=right; printf("%.6lf\n",ans);//电脑会四舍五入 return 0;}
c题:
# include<stdio.h># include<string.h># include<algorithm>using namespace std;int f[1001];struct node{ int a,b;}human[1001];int num1,num2,a1,b1,a2,b2;int main(){ int n; scanf("%d",&n); int i,j; for(i=1;i<=n;i++) {scanf("%d%d",&human[i].a,&human[i].b); } scanf("%d%d%d",&num1,&a1,&b1); scanf("%d%d%d",&num2,&a2,&b2); memset(f,-1000,sizeof(f)); for(i=0;i<=min(n,num2);i++) f[i]=human[i].a*a2+human[i].b*b2; f[0]=human[1].a*a1+human[1].b*b1; int ans=-1000000; for(i=1;i<=min(num1,n);i++) {for(j=1;j<=min(n-i,num2);j++) {f[j]=max(f[j-1]+human[i+j].a*a2+human[i+j].b*b2,f[j]+human[i+j].a*a1+human[i+j].b*b1); //printf("i:%d j:%d f:%d\n",i,j,f[j]); } if(f[n-i]>ans) ans=f[n-i]; } printf("%d\n",ans); return 0;}
以下内容仅供参考
b题:二分答案 然后check 类似bfs 从每一个没标号的点出发 距离小于mid的都标上号 看看用了几个号码 如果比k多就满足条件 check 复杂度为O(n)
c题:。。像我这种菜鸡最适合做这种题了。。。dp10分钟秒杀
f[i][j]=f[i][j]=max(f[i][j-1]+human[i+j].a*a2+human[i+j].b*b2,f[i-1][j]+human[i+j].a*a1+human[i+j].b*b1);
建议使用滚动数组
b代码:
# include<stdio.h># include<string.h># define EC(a) ((a)*(a))# define mod 10000000int n,k;struct node{ double x,y,z;}web[1001];double s[1001][1001];int vis[1001];bool tank(double define){ memset(vis,0,sizeof(vis)); int i,j,tot=0; int q[1010],front,rear; for(i=1;i<=n;i++) {if(!vis[i]) vis[i]=++tot; front=0,rear=1,q[0]=i; while(front<rear) { for(j=1;j<=n;j++) if(!vis[j]&&s[q[front]][j]<=define) {vis[j]=vis[i];q[rear++]=j; } front++; } } if(tot>=k) return true; return false;}int main(){ scanf("%d%d",&n,&k); double x,y,z; int i,j; for(i=1;i<=n;i++) {scanf("%lf%lf%lf",&x,&y,&z),web[i].x=x,web[i].y=y,web[i].z=z;} for(i=1;i<=n;i++) for(j=1;j<=n;j++) s[i][j]=EC(web[i].x-web[j].x)+EC(web[i].y-web[j].y)+EC(web[i].z-web[j].z); double left=0,right=1,mid; while(left+0.0000001<right) {mid=(left+right)/(2.0); // printf("left:%.7lf right:%.7lf mid:%.7lf\n",left,right,mid); if(!tank(mid)) right=mid-0.0000001; else left=mid; } double ans=right; printf("%.6lf\n",ans);//电脑会四舍五入 return 0;}
c题:
# include<stdio.h># include<string.h># include<algorithm>using namespace std;int f[1001];struct node{ int a,b;}human[1001];int num1,num2,a1,b1,a2,b2;int main(){ int n; scanf("%d",&n); int i,j; for(i=1;i<=n;i++) {scanf("%d%d",&human[i].a,&human[i].b); } scanf("%d%d%d",&num1,&a1,&b1); scanf("%d%d%d",&num2,&a2,&b2); memset(f,-1000,sizeof(f)); for(i=0;i<=min(n,num2);i++) f[i]=human[i].a*a2+human[i].b*b2; f[0]=human[1].a*a1+human[1].b*b1; int ans=-1000000; for(i=1;i<=min(num1,n);i++) {for(j=1;j<=min(n-i,num2);j++) {f[j]=max(f[j-1]+human[i+j].a*a2+human[i+j].b*b2,f[j]+human[i+j].a*a1+human[i+j].b*b1); //printf("i:%d j:%d f:%d\n",i,j,f[j]); } if(f[n-i]>ans) ans=f[n-i]; } printf("%d\n",ans); return 0;}