纪中游记(十四)
20190821
T0
初
一看题就联想到最小生成树,但没有再回头打这道题
复
先DFS枚举,在加上Prim
不多说了,我先回去复习最小生成树了
1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,m;
4 int p[20],l[20][20],ans[20],dis[20],h[20],lal=1000000,lap=1;
5 bool pd[20],yu[20];
6 void dfs(int x,int fak)
7 {
8 if(x==m)
9 {
10 memset(yu,0,sizeof(yu));
11 memset(dis,0x3f,sizeof(dis));
12 dis[h[1]]=0;
13 for(int i=1;i<m;i++)
14 {
15 int x=0;
16 for(int j=1;j<=m;j++)
17 {
18 if(!yu[h[j]]&&(x==0||dis[h[j]]<dis[h[x]]))
19 x=j;
20 }
21 yu[h[x]]=1;
22 for(int j=1;j<=m;j++)
23 {
24 if(!yu[h[j]])
25 dis[h[j]]=min(dis[h[j]],l[h[x]][h[j]]);
26 }
27 int numl=0,nump=0;
28 for(int i=2;i<=m;i++)
29 {
30 numl+=dis[h[i]];
31 }
32 for(int i=1;i<=m;i++)
33 {
34 nump+=p[h[i]];
35 }
36 if(numl*lap<nump*lal)
37 {
38 lap=nump;
39 lal=numl;
40 for(int i=1;i<=m;i++)
41 {
42 ans[i]=h[i];
43 }
44 }
45 }
46 return;
47 }
48 for(int i=fak+1;i<=n;i++)
49 {
50 if(!pd[i])
51 {
52 pd[i]=1;
53 x++;
54 h[x]=i;
55 dfs(x,i);
56 pd[i]=0;
57 x--;
58 }
59 }
60 }
61 int main()
62 {
63 // freopen("radio.in","r",stdin);
64 // freopen("radio.out","w",stdout);
65 scanf("%d%d",&n,&m);
66 for(int i=1;i<=n;i++)
67 {
68 scanf("%d",&p[i]);
69 }
70 for(int i=1;i<=n;i++)
71 {
72 for(int j=1;j<=n;j++)
73 {
74 scanf("%d",&l[i][j]);
75 }
76 }
77 dfs(0,0);
78 for(int i=1;i<=m;i++)
79 printf("%d ",ans[i]);
80 return 0;
81 }
终
复习中
T1
初
开始我计划用暴搜骗点分,结果一直到最后也没成功
复
一%一样的思路,换成DP就是60分(大雾)
正解是二分答案(完全懵逼)
三维不行那就二维,f[i][j]代表到前i个人,在1项目做了j个的情况下,2项目能做的最多的个数。
转移方程就是:f[i][j]=max(f[i][j],f[i-1][j-k]+(ans-k*one[i])/two[i])
1 #include<bits/stdc++.h>
2 using namespace std;
3 int f[105][105],n,m;
4 int one[105],two[105];
5 int main()
6 {
7 freopen("company.in","r",stdin);
8 freopen("company.out","w",stdout);
9 scanf("%d%d",&n,&m);
10 for(int i=1;i<=n;i++)
11 {
12 scanf("%d%d",&one[i],&two[i]);
13 }
14 int l=1,r=100,mid;
15 while(l<r)
16 {
17 mid=(l+r)/2;
18 memset(f,0xcf,sizeof(f));
19 f[0][0]=0;
20 for(int i=1;i<=n;i++)
21 {
22 for(int j=0;j<=m;j++)
23 {
24 for(int k=0;k<=j;k++)
25 {
26 if(k*one[i]>mid) break;
27 if((mid-k*one[i])/two[i]>=0)
28 f[i][j]=max(f[i][j],f[i-1][j-k]+(mid-k*one[i])/two[i]);
29 }
30 }
31 }
32 if(f[n][m]>=m) r=mid;
33 else l=mid+1;
34 }
35
36 cout<<r;
37 return 0;
38 }
终
还要多练DP
T2
初
哇~这题竟然这么水,于是便开心的打起了Floyd,一测样例正确,便满怀信心的提交,
结果爆零(wrong answer)
复
怀疑是精度问题,疯狂调试,结果:
最后LXL大佬一语道破天机:要在最后才能取整!
于是一改便AC了
终
精度害死蒟蒻系列