测试...挺坑的...
背包的地方想到了化为多重背包进行优化,然而写不出来...
中国剩余定理还是细节有问题,取模乘积还是不熟练
总之要多做题加强.
T1 AC 01背包数据挺水的... 板子过了
代码
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define rep(i,a,n) for(int i = a;i <= n;i++) 7 using namespace std; 8 typedef long long LL; 9 int read() { 10 int ans = 0,fu = 1; 11 char ch = getchar(); 12 while(ch < '0' || ch > '9') { 13 if(ch == '-') fu = -1; 14 ch = getchar(); 15 } 16 while(ch >= '0' && ch <= '9') { 17 ans = ans * 10 + ch - '0'; 18 ch = getchar(); 19 } 20 return ans * fu; 21 } 22 23 //head 24 const int N = 10010; 25 int w[N],val[N],dp[N]; 26 27 int main() { 28 freopen("medic.in","r",stdin); 29 freopen("medic.out","w",stdout); 30 int maxx = read(); 31 int n = read(); 32 rep(i,1,n) { 33 w[i] = read(); 34 val[i] = read(); 35 } 36 rep(i,1,n) 37 for(int j = maxx; j >= w[i]; j--) 38 dp[j] = max(dp[j],dp[j - w[i]] + val[i]); 39 printf("%d ",dp[maxx]); 40 return 0; 41 }
T2 40% 写的格式和顺序有问题
改完标程
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; LL a[15],b[15],m[15],res[15]; LL read() { LL ans = 0,fu = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') fu = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans = ans * 10 + ch - '0'; ch = getchar(); } return ans * fu; } //head LL exgcd(LL a,LL b,LL &x,LL &y) { if(!b) { x = 1,y = 0; return a; } LL d = exgcd(b,a % b,y,x); y -= x * (a / b); return d; } int main() { freopen("cao.in","r",stdin); freopen("cao.out","w",stdout); int n = read(); LL mod = 1; for(int i = 1;i <= n;i++) { a[i] = read(); mod *= a[i]; b[i] = read(); } for(int i = 1;i <= n;i++) { m[i] = mod / a[i]; LL x,y; exgcd(m[i],a[i],x,y); //保证x*m[i]在%a[i]时为1,%a[j]时为0(j!=i) x = (x + a[i]) % a[i];//x>0 res[i] = x * m[i] * b[i];//res[i] % a[i] == b[i],res[i] % b[j] == 0(j != i); } LL ans = 0; for(int i = 1;i <= n;i++) ans += res[i]; ans %= mod; printf("%lld ",ans); return 0; } /* s:3 3 1 5 1 7 2 p: 16 */
T3 40% 数据范围扩大后可以用多重背包变nlgn
AC标程
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) using namespace std; typedef long long LL; int read() { int ans = 0,fu = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') fu = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans = ans * 10 + ch - '0'; ch = getchar(); } return ans * fu; } //head*** const int N = 100005; int dp[N],num[101]; void OIbag(int cst,int val,int n)//01背包封装成函数 { per(i,n,cst) dp[i] = max(dp[i],dp[i - cst] + val); } void cbag(int cst,int val,int n)//完全背包封装成函数 { rep(i,cst,n) dp[i] = max(dp[i],dp[i - cst] + val); } int mtbag(int m)//多重背包 { rep(i,0,100)//遍历每种物品 { int c = i / 10; int v = i % 10; if(num[i] * v >= m) cbag(c,v,m); //如果全装进去已经超了重量,那么就用完全背包去套 else { int k = 1; //取得光的话,去遍历每种取法 //优化:这里用到是二进制思想,把复杂度从num[i]变成了lognum[i] while(k < num[i]) { OIbag(k * c,k * v,m); num[i] -= k; k *= 2; } OIbag(num[i] * c,num[i] * v,m);//rest } } return dp[m]; } int main() { freopen("medic2.in","r",stdin); freopen("medic2.out","w",stdout); int n = read(); int maxx = read(); //优化:由于t和v排列最多101种,化为多重背包 rep(i,1,n) { int dx = read(); int dy = read(); num[dx * 10 + dy]++; } printf("%d ",mtbag(maxx)); return 0; }
By ProphetB