第七周 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 }
6.30
开了个dp题。感觉太急不好。先放着。
晚上打了个CF。
7.1
想补CF的C。好像想错了- -
7.2
在自习室数分看累的时候顺便写了下伪代码。
晚上回来敲完。把n-1写成n-2了竟然能成功跑到第27个点- -
改成n-1就过了。
题意:
亚瑟菌有一个桌子。桌子有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 }
司老大说不要做水题。
然而这种没有啥算法的题对我已经够呛了。
7.3
前几天开的一个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 }
7.4
经典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 }
晚上打了个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 }
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 }
不转A协blog了。都没人发。显得我好sb。