其他分享
首页 > 其他分享> > 19.3.12 练习赛

19.3.12 练习赛

作者:互联网

昨日练习赛,很简单,但做的并不好

T1:暴力枚举100个其余等效状态O(1)加入答案,虽然正解好像是容斥原理

 1 n=rd(),m=rd();
 2      if(n<3 || m<3) {cout<<0;return 0;}
 3      FOR(i,3,n) cc[i]=(i-2)*(m-2);
 4       //FOR(i,1,n) cout<<cc[i]<<" ";cout<<endl;
 5     FOR(i,1,n-2) 
 6     {
 7           ll ansn=0;
 8           FOR(j,1,m-2)
 9         {
10               ll ansnn=0;
11               ansnn+=cc[i-1]+cc[n-i-2];
12               ansnn+=(max(j-3,lng)+max(m-j-4,lng))*((i>=3)+(i>=2)+1)+(max(j-2,lng)+max(m-j-3,lng))*((i<=n-3)+(i<=n-4));
13               ansn+=ansnn;
14               if(m>=10 && j==4) {ansn+=(m-9)*ansnn;j=m-5;}
15         }
16         ans+=ansn;
17         if(n>=10 && i==4) {ans+=(n-9)*ansn;i=n-5;}
18     }
19     cout<<ans;
View Code

结果最后画蛇添足改错了

T2:DP转移 结果被数学期望吓蒙了

光看时间复杂度,50 分是可以拿满分的,但是存在一个严峻问题:如果是随机数据,数据生成后单个概率大约在 0.3 ∼ 0.4 ,而 0.4300 精度早就在能承受的范围后面好远了。

所以就提出一种解决方案,把所有的概率取个对数,底数随便定(自带log()函数即可),把乘法改成加法即可

 1     scanf("%d%d%d",&n,&m,&k);
 2       FOR(i,1,k) FOR(j,1,n) f[i][j]=-(1<<30);
 3       FOR(i,1,n) FOR(j,1,n) scanf("%lf",&a[i][j]),a[i][j]=log(a[i][j]);
 4       FOR(i,1,n) FOR(j,1,m) scanf("%lf",&b[i][j]),b[i][j]=log(b[i][j]);
 5       FOR(i,1,n) scanf("%lf",&f[1][i]),f[1][i]=log(f[1][i]);
 6       FOR(i,1,k) scanf("%d",&hd[i]);
 7       FOR(i,1,n) f[1][i]+=b[i][hd[1]];
 8       FOR(i,2,k) FOR(j,1,n) FOR(kk,1,n) 
 9     {
10         double tp=f[i-1][kk]+a[kk][j]+b[j][hd[i]];
11         if(f[i][j]<tp)
12         {
13             f[i][j]=tp;
14             pre[i][j]=kk;
15         }
16     }
17     int ss=1;
18     FOR(i,2,n) if(f[k][i]>f[k][ss]) ss=i;
19     For(i,k,1) {ans[i]=ss;ss=pre[i][ss];}
20     FOR(i,1,k) printf("%d ",ans[i]);

T3 

贪心. 考虑一个更简单的问题:

给一个长为 N 的序列,有 N 个车,每个车可以放入区间 [l,r] 的任意一个位置,每个位置最多可以放 1 个车。

将每个车l 为第一关键字,r 为第二关键字排序。从左向右扫描整个序,每扫到一个位置,将能放在该位置上的,当前还未放置的所有车中 r 最小的那个放在该位置。每个位置确定车是 O(n) 的,总复杂度 O(n2) 。

回归到 2 维, 注意到每一维是独立的,即确定了所有车第一维的位置, 第二维不受影响. 故每一维单独做即可

在 80 分基础上,用堆维护当前未放置的所有车中 r 最小的车. 每个位置,确定车是 O(logn) 的, 总复杂度 O(nlogn) 。

 1 //参考过jxl_orz的程序
 2 const int N=100010;
 3 struct car{int u,d,l,r;}a[N];
 4 struct node
 5 {
 6     int cc,id;
 7     node(int CC,int ID){cc=CC;id=ID;}
 8     bool operator < (const node a)const {return cc==a.cc?id>a.id:cc>a.cc;}
 9 };
10 int x[N],y[N];
11 int n;
12 priority_queue<node> s1,s2;
13 vector<int> ss1[N],ss2[N];
14 
15 void solx()
16 {
17     FOR(i,1,n) ss1[a[i].u].push_back(i);
18     FOR(i,1,n)
19     {
20         int hhh=ss1[i].size()-1;
21         //cerr<<i<<" "<<hhh<<endl;
22         FOR(j,0,hhh) s1.push((node){a[ss1[i][j]].d,ss1[i][j]});//cerr<<ss1[i][j]<<" ",
23         //cerr<<endl<<s1.top().cc<<" "<<s1.top().id<<endl;
24         x[s1.top().id]=i;s1.pop();
25     }
26 }
27 
28 void soly()
29 {
30     FOR(i,1,n) ss2[a[i].l].push_back(i);
31     FOR(i,1,n)
32     {
33         int hhh=ss2[i].size()-1;
34         FOR(j,0,hhh) s2.push(node(a[ss2[i][j]].r,ss2[i][j]));
35         y[s2.top().id]=i;s2.pop();
36     }
37 }
38 
39 int main()
40 {
41       freopen("chessboard.in","r",stdin);
42       freopen("chessboard.out","w",stdout);
43       n=rd();
44       if(n==1) {cout<<"1 1";return 0;}
45       FOR(i,1,n) a[i].u=rd(),a[i].d=rd(),a[i].l=rd(),a[i].r=rd();
46       //FOR(i,1,n) cout<<a[i].u<<" "<<a[i].d<<" "<<a[i].l<<" "<<a[i].r<<endl;
47       solx();soly();
48       FOR(i,1,n) printf("%d %d\n",x[i],y[i]);
49       return 0;
50 }

标签:12,ss,19.3,int,位置,cc,练习赛,ans,id
来源: https://www.cnblogs.com/universeplayer/p/10522934.html