hdu-4901-The Romantic Hero
problem
给你n[<=1000]个数ai[0, 1023]。你可以选两个两个集合,满足1.前一个集合的最大坐标小于后一个集合的最小坐标;2.前一个集合的亦或和等于后一个集合的与和。
问你有多少中选法。
think
b[i][j]表示第一个数到第i个数,一定选择了第i个数,亦或和是j,的方案数。
c[i][j]表示第i个数到第n个数,不一定选择了第i个数,亦或和是j,的方案数。
code
const LL mod = 1000000007;
int a[1111];
int b[1111][1111], bb[1111][1111], c[1111][1111];
int main(){
int T, tt = 0;
scanf("%d", &T);
while(T--){
int n;
scanf("%d", &n);
int sum = 0;
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
sum =(sum | a[i]);
}
++sum;
memset(b, 0, sizeof(b));
memset(bb, 0, sizeof(bb));
memset(c, 0, sizeof(c));
b[1][a[1]] = 1;
bb[1][a[1]] = 1;
c[n][a[n]] = 1;
for(int i = n-1; i >= 1; --i){
c[i][a[i]] += 1;
c[i][a[i]] %= mod;
for(int j = 0; j < sum; ++j){
c[i][j] += c[i+1][j];
c[i][j] %= mod;
c[i][j&a[i]] += c[i+1][j];
c[i][j&a[i]] %= mod;
}
}
for(int i = 2; i <= n; ++i){
bb[i][a[i]] += 1;
bb[i][a[i]] %= mod;
b[i][a[i]] += 1;
b[i][a[i]] %= mod;
for(int j = 0; j < sum; ++j){
bb[i][j] += bb[i-1][j];
bb[i][j] %= mod;
bb[i][j^a[i]] += bb[i-1][j];
bb[i][j^a[i]] %= mod;
b[i][j^a[i]] += bb[i-1][j];
b[i][j^a[i]] %= mod;
}
}
LL ans = 0;
for(int i = 1; i < n; ++i){
for(int j = 0; j < sum; ++j){
ans = (ans + (LL)b[i][j] * c[i+1][j]) % mod;
}
}
printf("%I64d\n", ans);
}
return 0;
}
/*
2
3 1 2 3
4 1 2 3 3
*/
hdu-4906-Our happy ending
problem
有多少这样的序列,有n个数,每个数[0,L], 从中选择一些数的和可以是k.
其中n和k不超过20,L不超过1e9
think
状压+背包
复杂数:T(case数)*n*(1<<k)*k
code
const LL mod = 1e9 + 7;
int dp[1<<20];
int main(){
int n, k, L;
int T, tt = 0;
scanf("%d", &T);
while(T--){
scanf("%d%d%d", &n, &k, &L);
int add = 0;
if(L > k){
add = L - k;//比k大的都不改变状态
L = k;
}
memset(dp, 0, sizeof(dp));
dp[0] = 1;
int bag = (1<<k) - 1;
int mx = 0;
while(n--){
for(int i = mx; i >= 0; --i) if(dp[i]){
int tmp = dp[i];
for(int j = 1; j <= L; ++j){
int ii = i|(1<<j-1)|(((LL)i<<j)&bag);
dp[ii] = dp[ii] + tmp;
if(dp[ii] >= mod) dp[ii] -= mod;
if(ii > mx) mx = ii;
}
dp[i] = dp[i] + (LL)add*tmp%mod;
if(dp[i] >= mod) dp[i] -= mod;
}
}
int ans = 0;
for(int i = (1<<k-1), ii = (1<<k); i < ii; ++i) {
ans = ans + dp[i];
if(ans >= mod) ans -= mod;
}
printf("%d\n", ans);
}
return 0;
}
本文解析了两道算法竞赛题目,包括“The Romantic Hero”和“Our happy ending”。前者要求找出特定条件下数对的选择方法,后者则关注于寻找符合特定条件的序列数量。文中详细介绍了状态压缩与动态规划等高级算法的应用。
591

被折叠的 条评论
为什么被折叠?



