hiho_offer收割18_题解报告_差第四题
I.求逆元
欧几里得方法
II.模拟
细心+耐心
*本人感悟:
自己的错误在于:
对于这道模拟题没有耐心静下来一字一字看题,一行一行调错,一步一步调试,我要引以为戒。
III.dp
f[i][j][k]=max(f[i-1][j][k],min(f[i-1][t][k-1])+value[i][k])
t=0,1,…,801
i为第i个曲子(长度为3)
j为至今已进行j次的和弦改变(j<=c(c为允许和弦改变的最多次数))
k为第k种和弦的方法
value[i][k]为用对第i个曲子用第k个和弦的不和谐值
本人想到的进一步优化(本题不用):
1.求出全程不能变音的最小值
2.对于某个变音方法,如果其值已经大于最小值,则该方法不能继续进行下去
具体操作:
把对应第1~i个曲子可以实现的和弦存放到数组,生成第1~i+1个曲子可以实现的和弦
时间复杂度:
i<=1000
j<=20
k<=802
对于每个i,k,求出一次min(f[i-1][t][k-1])即可
O(nk*802)
1000*20*802=16040000
可在一秒内解决
*另:注意数组维数的范围
如发现错误,可在各个位置设置“输出一个数”,看哪里不正常,那么就是哪里出错了
*测试数据:
如n=1000,k=20
其它全为0
判断是否数组开的正确
IV.
实际上,没多少斤两就不要想第四题了,看看题目和测试数据就知道是不想让你用简单方法拿点分了
反正不会做
下面是想法:
不同的分图没有边相连,不互相影响,可分开考虑
以k个点为标准点,分别考虑这k个点是否发生故障,除去??? 不行,2^k 太大了
有第i个点和有第j点,
当某边在/不在时
当某点在/不在时
当n很大时
当m很大时
极限数据:
100000个点,编号为前400的点,每个点之间都有一个边相连;剩下的点都仅与编号为1的点相连
1.
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 long s,t; 5 6 void gcd(long x,long y) 7 { 8 if (y==0) 9 { 10 s=1; 11 t=0; 12 return; 13 } 14 long r,q; 15 r=x/y; 16 gcd(y,x%y); 17 q=s; 18 s=t; 19 t=q-r*t; 20 } 21 22 int main() 23 { 24 long a,b,p; 25 scanf("%ld%ld%ld",&a,&b,&p); 26 b=b%p; 27 gcd(p,b); 28 t=t%p+p; 29 printf("%ld\n",a*t%p); 30 return 0; 31 }
2.
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdbool.h> 4 #include <string.h> 5 6 struct node 7 { 8 long f[4]; 9 long a[3]; 10 }pai[10]; 11 12 long n; 13 14 bool judge() 15 { 16 long j,k,g; 17 //1 18 for (j=0;j<4;j++) 19 { 20 g=0; 21 for (k=0;k<n;k++) 22 g+=pai[k].f[j]; 23 if (g==5) 24 return true; 25 } 26 //2 27 for (j=0;j<n;j++) 28 if (pai[j].a[0]>0) 29 break; 30 if (j!=n) 31 { 32 for (j=0;j<n;j++) 33 if (pai[j].f[0]+pai[j].f[1]+pai[j].f[2]+pai[j].f[3]>0) 34 break; 35 if (j!=n) 36 { 37 for (j=0;j<n;j++) 38 if (pai[j].f[3]>0) 39 break; 40 if (j==n) 41 return true; 42 } 43 } 44 //3 45 for (j=0;j<n;j++) 46 if (pai[j].a[1]>0) 47 break; 48 if (j!=n) 49 { 50 for (j=0;j<n;j++) 51 if (pai[j].f[0]+pai[j].f[1]+pai[j].f[2]+pai[j].f[3]>0) 52 break; 53 if (j!=n) 54 { 55 for (j=0;j<n;j++) 56 if (pai[j].f[1]>0) 57 break; 58 if (j==n) 59 return true; 60 } 61 } 62 //4 63 for (j=0;j<n;j++) 64 if (pai[j].a[2]>0) 65 break; 66 if (j!=n) 67 { 68 for (j=0;j<n;j++) 69 if (pai[j].f[0]+pai[j].f[1]+pai[j].f[2]+pai[j].f[3]>0) 70 break; 71 if (j!=n) 72 return true; 73 } 74 return false; 75 } 76 77 int main() 78 { 79 long c,g,t,i,j,k,sum[10],tot[10],num; 80 char s[50]; 81 scanf("%ld%ld",&n,&c); 82 for (i=0;i<n;i++) 83 sum[i]=10000000; 84 for (i=0;i<n;i++) 85 tot[i]=0; 86 num=0; 87 for (i=1;i<=c;i++) 88 { 89 scanf("%s",s); 90 if (strcmp(s,"Fruit")==0) 91 { 92 tot[num]++; 93 sum[num]--; 94 for (j=0;j<4;j++) 95 pai[num].f[j]=0; 96 for (j=0;j<3;j++) 97 pai[num].a[j]=0; 98 scanf("%ld",&g); 99 for (j=1;j<=g;j++) 100 { 101 scanf("%ld",&t); 102 pai[num].f[t]++; 103 } 104 num=(num+1)%n; 105 } 106 else if (strcmp(s,"Animal")==0) 107 { 108 tot[num]++; 109 sum[num]--; 110 for (j=0;j<4;j++) 111 pai[num].f[j]=0; 112 for (j=0;j<3;j++) 113 pai[num].a[j]=0; 114 scanf("%ld",&t); 115 pai[num].a[t]=1; 116 num=(num+1)%n; 117 } 118 else 119 { 120 scanf("%ld",&t); 121 if (judge()==true) 122 { 123 for (j=0;j<n;j++) 124 sum[t]+=tot[j]; 125 for (j=0;j<n;j++) 126 { 127 tot[j]=0; 128 for (k=0;k<4;k++) 129 pai[j].f[k]=0; 130 for (k=0;k<3;k++) 131 pai[j].a[k]=0; 132 } 133 } 134 else 135 { 136 sum[t]-=n; 137 for (j=0;j<n;j++) 138 sum[j]++; 139 } 140 num=t; 141 } 142 //printf("%ld %ld %ld\n",sum[0],sum[1],sum[2]); 143 } 144 for (i=0;i<n;i++) 145 printf("%ld\n",sum[i]); 146 return 0; 147 }
3.
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #define maxf 10000000 5 //max=400*3000=1200000 6 7 long music[3001],value[1001][802],f[1001][21][802],ch[1001]; 8 9 long min(long a,long b) 10 { 11 if (a>b) 12 return b; 13 else 14 return a; 15 } 16 17 int main() 18 { 19 long n,g,i,j,k,l,m,pr; 20 scanf("%ld%ld",&n,&g); 21 for (i=1;i<=3*n;i++) 22 scanf("%ld",&music[i]); 23 for (i=0;i<=400;i++) 24 { 25 j=i-200; 26 l=0; 27 m=0; 28 for (k=1;k<=n;k++) 29 { 30 m++; 31 value[m][i]=0; 32 l++; 33 value[m][i]+=abs(j-music[l]); 34 l++; 35 value[m][i]+=abs(j+4-music[l]); 36 l++; 37 value[m][i]+=abs(j+7-music[l]); 38 } 39 } 40 41 for (i=401;i<=801;i++) 42 { 43 j=i-601; 44 l=0; 45 m=0; 46 for (k=1;k<=n;k++) 47 { 48 m++; 49 value[m][i]=0; 50 l++; 51 value[m][i]+=abs(j-music[l]); 52 l++; 53 value[m][i]+=abs(j+3-music[l]); 54 l++; 55 value[m][i]+=abs(j+7-music[l]); 56 } 57 } 58 59 for (i=1;i<=n;i++) 60 for (j=1;j<=g;j++) 61 for (k=0;k<802;k++) 62 f[i][j][k]=maxf; 63 64 for (k=0;k<802;k++) 65 f[0][0][k]=0; 66 for (i=1;i<=n;i++) 67 for (k=0;k<802;k++) 68 f[i][0][k]=f[i-1][0][k]+value[i][k]; 69 70 pr=maxf; 71 //2 72 for (i=2;i<=n;i++) 73 { 74 //0 <g 75 for (j=0;j<min(i-1,g);j++) 76 { 77 ch[j]=maxf; 78 for (k=0;k<802;k++) 79 ch[j]=min(ch[j],f[i-1][j][k]); 80 } 81 //1(0 不用计算) 82 for (j=0;j<=min(i-1,g);j++) 83 { 84 for (k=0;k<802;k++) 85 { 86 f[i][j][k]=f[i-1][j][k]+value[i][k]; 87 if (j!=0) 88 f[i][j][k]=min(f[i][j][k],ch[j-1]+value[i][k]); 89 } 90 } 91 } 92 93 for (j=0;j<=g;j++) 94 for (k=0;k<802;k++) 95 pr=min(pr,f[n][j][k]); 96 97 printf("%ld\n",pr); 98 return 0; 99 }
by lzu_cgb
share & spread ideas