第七周 6.28-7.4

6.28

 救命要考C艹了。

6.29

括号匹配(二)

老看题解。不开心。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <algorithm>
 5 using namespace std;
 6 char str[105];
 7 int dp[105][105];
 8 
 9 int main(void)
10 {
11     int N;cin>>N;
12     while(N--)
13     {
14         scanf("%s",str);
15         int len=strlen(str);
16         memset(dp,0,sizeof(dp));
17         for(int i=0;i<len;i++) dp[i][i]=1;
18         for(int l=1;l<len;l++)
19             for(int s=0;s+l<len;s++)
20             {
21                 dp[s][s+l]=dp[s][s+l-1]+1;
22                 if(str[s+l]==')')
23                     for(int t=s;t<s+l;t++)
24                         if(str[t]=='(')
25                             dp[s][s+l]=min(dp[s][s+l],dp[s][t-1]+dp[t+1][s+l-1]);
26                 if(str[s+l]==']')
27                     for(int t=s;t<s+l;t++)
28                         if(str[t]=='[')
29                             dp[s][s+l]=min(dp[s][s+l],dp[s][t-1]+dp[t+1][s+l-1]);
30             }
31         printf("%d\n",dp[0][len-1]);
32     }
33     return 0;
34 }
Aguin

 6.30

开了个dp题。感觉太急不好。先放着。

晚上打了个CF。

7.1

想补CF的C。好像想错了- -

7.2

在自习室数分看累的时候顺便写了下伪代码。

晚上回来敲完。把n-1写成n-2了竟然能成功跑到第27个点- -

改成n-1就过了。

C - Arthur and Table

题意:

亚瑟菌有一个桌子。桌子有n个腿。每个腿有一个长度l和锯掉该腿所需能量d。

他要锯掉若干条腿。使桌子平稳。当桌子的最长腿占桌腿总数的一半以上时我们认为桌子是平稳的。

求所需能量的最小值。

题解:

看的官方题解。理解上有点偏差。就按自己思路了。

倘若以l为最长腿的情况有最优解。

那么需要先锯掉所有大于l的腿。再在小于l的腿中锯掉能量值小的。直到最长腿数大于总数的一半。

由于锯腿能量值在1-200之间,读数据的时候用cnt[]数组存各能量的腿数。

先按桌腿长sort一遍。然后从最长的腿开始扫。

变量m表示小于等于li的腿长度。tot表示长度等于li的腿数。sum表示锯掉小于等于li的所有腿所需能量。

cur表示当前情况所需能量值。ans是答案。

每扫一腿在cnt[]里把该能量值的腿-1。sum里加上该腿的能量值。

每扫到长度为li的腿的最后一个时。计算以li为最长腿的情况所需的能量值。

cur初始是sum。即锯掉所有大于li已经花费的能量。

判断tot是否已经大于总数的一半。否则扫cnt[]从最小的开始加至满足条件为止。

ans取所有cur的最小值。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <algorithm>
 4 using namespace std;
 5 int cnt[201]={0};
 6 
 7 struct node
 8 {
 9     int l,d;
10 }leg[100000+10];
11 
12 bool cmp(node x,node y)
13 {
14     return x.l>y.l;
15 }
16 
17 int main(void)
18 {
19     int n; cin>>n;
20     for(int i=0;i<n;i++) scanf("%d",&leg[i].l);
21     for(int i=0;i<n;i++) {scanf("%d",&leg[i].d);cnt[leg[i].d]++;}
22     sort(leg,leg+n,cmp);
23     int m=n,tot=0,sum=0,cur=0,ans=2147483647;
24     for(int i=0;i<n;i++)
25     {
26         tot++; cnt[leg[i].d]--; sum+=leg[i].d;
27         if(i==n-1||leg[i+1].l!=leg[i].l)
28         {
29             if(tot<=m/2)
30             {
31                 int k=m+1-2*tot;
32                 for(int j=1;j<=200;j++)
33                     if(cnt[j])
34                         if(cnt[j]<k) {cur+=cnt[j]*j; k-=cnt[j];}
35                         else {cur+=k*j;break;}
36             }
37             ans=min(ans,cur);
38             m-=tot; tot=0; cur=sum;
39         }
40     }
41     printf("%d\n",ans);
42     return 0;
43 }
Aguin

司老大说不要做水题。

然而这种没有啥算法的题对我已经够呛了。

7.3

P1011 传纸条

前几天开的一个dp题。

思考两个问题:

1.如何表示状态。

2.如何剔除不符合条件的状态。

偷看题解。用dp[dep][x1][x2]表示状态。

dep是步数。x为两点横坐标位置。x1<x2为符合条件的状态。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <algorithm>
 5 using namespace std;
 6 int a[51][51],D[100][51][51];
 7 
 8 int dp(int dep,int i,int j)
 9 {
10     if(D[dep][i][j]>=0) return D[dep][i][j];
11     if(dep==1&&i==1&&j==2) return D[dep][i][j]=a[2][1]+a[1][2];
12     int ret=-1;
13     if(j<=dep) ret=max(ret,dp(dep-1,i,j)+a[dep-i+2][i]+a[dep-j+2][j]);
14     if(i>1) ret=max(ret,dp(dep-1,i-1,j-1)+a[dep-i+2][i]+a[dep-j+2][j]);
15     if(j<=dep&&i>1) ret=max(ret,dp(dep-1,i-1,j)+a[dep-i+2][i]+a[dep-j+2][j]);
16     if(j-1>i) ret=max(ret,dp(dep-1,i,j-1)+a[dep-i+2][i]+a[dep-j+2][j]);
17     return D[dep][i][j]=ret;
18 }
19 
20 int main(void)
21 {
22     memset(D,-1,sizeof(D));
23     int m,n; cin>>m>>n;
24     for(int i=1;i<=m;i++)
25         for(int j=1;j<=n;j++)
26             scanf("%d",&a[i][j]);
27     printf("%d\n",dp(m+n-3,n-1,n));
28     return 0;
29 }
Aguin

 7.4

P1198 最优矩阵连乘

经典dp吧。和前面写过的一个比较像。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 using namespace std;
 5 int a[101],dp[101][101]={0};
 6 
 7 int main(void)
 8 {
 9     int n; cin>>n;
10     for(int i=0;i<=n;i++) scanf("%d",a+i);
11     for(int len=1;len<n;len++)
12         for(int start=1;start+len<=n;start++)
13         {
14             int tem=2147483647;
15             for(int pos=start;pos<=start+len-1;pos++)
16                 tem=min(tem,dp[start][pos]+dp[pos+1][start+len]+a[pos]*a[start-1]*a[start+len]);
17             dp[start][start+len]=tem;
18         }
19     printf("%d\n",dp[1][n]);
20     return 0;
21 }
Aguin

 

晚上打了个BC。

HDU 5276 YJC tricks time

第一眼傻。这个钟怎么看阿。

然后意识到和钟并没有半毛钱关系。

写完初测过。感觉还挺水。

hack的时候发现自己写错一个地方。然而没有人来hack我。

终测跪。发现写错不止一个地方……

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <algorithm>
 4 using namespace std;
 5 
 6 struct time
 7 {
 8     int h,m,s,d;
 9 }T[12*60*6];
10 
11 int main(void)
12 {
13     int cnt=0,d;
14     for(int h=0;h<=11;h++)
15         for(int m=0;m<=59;m++)
16             for(int s=0;s<=50;s+=10)
17             {
18                 T[++cnt].h=h; T[cnt].m=m; T[cnt].s=s;
19                 int d1=360000*h+6000*m+100*s,d2=72000*m+1200*s;
20                 d=max(d1,d2)-min(d1,d2);
21                 if(d>2160000) d=2*2160000-d;
22                 T[cnt].d=d;
23             }
24     while((scanf("%d",&d))!=EOF)
25         for(int i=1;i<=cnt;i++)
26             if(T[i].d==d) printf("%02d:%02d:%02d\n",T[i].h,T[i].m,T[i].s);
27     return 0;
28 }
Aguin

 

HDU 5277 YJC counts stars

根本没意识到max=4实在是迟钝。

神奇的暴力即可。如果意识到max=4的话可能会尝试吧……

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <vector>
 4 using namespace std;
 5 vector <int> vec[1001];
 6 
 7 int main(void)
 8 {
 9     int n,m;
10     while(cin>>n>>m)
11     {
12         for(int i=1;i<=n;i++)
13         {
14             vec[i].clear();
15             int x,y;
16             scanf("%d%d",&x,&y);
17         }
18         for(int i=0;i<m;i++)
19         {
20             int u,v;
21             scanf("%d%d",&u,&v);
22             vec[u].push_back(v);
23             vec[v].push_back(u);
24         }
25         int a=0,b=0,c=0;
26         for(int t1=1;t1<=n;t1++)
27             for(int i=0;i<vec[t1].size();i++)
28             {
29                 int t2=vec[t1][i];
30                 a++;
31                 for(int j=0;j<vec[t2].size();j++)
32                 {
33                     int t3=vec[t2][j];
34                     if(t3!=t1)
35                     {
36                         int ok=0;
37                         for(int k=0;k<vec[t3].size();k++)
38                             if(vec[t3][k]==t1) {ok=1;break;}
39                         if(ok)
40                         {
41                             b++;
42                             for(int k=0;k<vec[t3].size();k++)
43                             {
44                                 int t4=vec[t3][k];
45                                 if(t4!=t1&&t4!=t2)
46                                 {
47                                     int ok1=0,ok2=0;
48                                     for(int l=0;l<vec[t4].size();l++)
49                                     {
50                                         if(vec[t4][l]==t1) ok1=1;
51                                         else if(vec[t4][l]==t2) ok2=1;
52                                         if(ok1&&ok2) break;
53                                     }
54                                     if(ok1&&ok2) c++;
55                                 }
56                             }
57                         }
58                     }
59                 }
60             }
61         a/=2; b/=6; c/=24;
62         if(c) printf("4 %d\n",c);
63         else if(b) printf("3 %d\n",b);
64         else if(a) printf("2 %d\n",a);
65         else printf("1 %d\n",n);
66     }
67     return 0;
68 }
Aguin

 

不转A协blog了。都没人发。显得我好sb。

posted @ 2015-06-28 14:10  Aguin  阅读(186)  评论(0编辑  收藏  举报