纪中游记(十四)

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 } 
special code

还要多练DP

T2

哇~这题竟然这么水,于是便开心的打起了Floyd,一测样例正确,便满怀信心的提交,

结果爆零(wrong answer

怀疑是精度问题,疯狂调试,结果:

观看惨案

最后LXL大佬一语道破天机:要在最后才能取整!

于是一改便AC

精度害死蒟蒻系列

posted @ 2019-08-21 21:42  HHHG  阅读(150)  评论(0编辑  收藏  举报