UVALive - 8144 Sacred Scarecrows DP + FMT 未解决

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/meopass/article/details/79977631

简略题意:RC的庄稼地,有些地方已经种了庄稼了。现在需要放置一些稻草人,使得满足以下两个条件:
1. 所有行都包含稻草人。
2. 相邻的两列至少包含两个稻草人。

这题目前还没有AC,但是值得记录。

注意到行很少,因此可以状压进行DP
dp[i][0/1][j]代表,前i列的稻草人存放了那些行,当前列是否有稻草人。

代表集合并卷积,那么转移有如下:
1.dp[i][0]=dp[i1][1]g[0]
2.dp[i][1]=dp[i1][0]g/g[0]+dp[i1][0]g/g[0]=(dp[i1][0]+dp[i1][1])g/g[0]
障碍物的处理直接把对应卷上的g给置零即可,所以可以用FMT来优化到R(2R)C
经过用assert得出测试数据至少有20组…上述算法无法通过。

qls给出了如下解法:
对行容斥,可以知道每列有多少空地,然后 O(c)dp.
容斥用 dfs 枚举集合可以 2r,可以做到 O(2RC).
暂时还没太理解,先想一想。

#define others
#ifdef poj
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#endif // poj
#ifdef others
#include <bits/stdc++.h>
#endif // others
//#define file
#define all(x) x.begin(), x.end()
using namespace std;
#define eps 1e-8
const double pi = acos(-1.0);

typedef long long LL;
typedef unsigned long long ULL;
void umax(int &a, int b) {
    a = max(a, b);
}
void umin(int &a, int b) {
    a = min(a, b);
}
int dcmp(double x) {
    return fabs(x) <= eps?0:(x > 0?1:-1);
}
void file() {
    freopen("data_in.txt", "r", stdin);
    freopen("data_out.txt", "w", stdout);
}

const LL mod = 1e9+7;

int r, c, lim;
LL dp[2][2][20000], f[20000], g[20000], h[20000];
char G[16][1100];

LL add(LL a, LL b) {
    a += b;
    if(a >= mod) a -= mod;
    return a;
}

LL mul(LL a, LL b) {
    LL sum = 1ll * a * b;
    if(sum >= mod) a %= mod;
    return sum;
}

LL sub(LL a, LL b) {
    a -= b;
    if(a < 0) a += mod;
    return a;
}

void FMT(int col, int on) {
    for(int i = 0; i < lim; i++) g[i] = 0;
    if(on) {
        for(int i = 1; i < lim; i++) {
            bool isok = 1;
            for(int j = 0; j < r; j++) {
                if((i & (1 << j)) && G[j][col] == 'v') isok = 0;
            }
            if(isok) g[i] = 1;
        }
    } else {
        g[0] = 1;
    }
    for(int i = 0; i < r; i++)
        for(int j = 0; j < lim; j++)
            if((j >> i) & 1)
                f[j] = add(f[j], f[j^(1<<i)]);
    for(int i = 0; i < r; i++)
        for(int j = 0; j < lim; j++)
            if((j >> i) & 1)
                g[j] = add(g[j], g[j^(1<<i)]);
    for(int i = 0; i < lim; i++)
        h[i] = mul(f[i], g[i]);
    for(int i = 0; i < r; i++)
        for(int j = 0; j < lim; j++)
            if((j>>i)&1)
                h[j] = sub(h[j], h[j^(1<<i)]);
}

void cpy(LL x[], LL y[]) {
    for(int i = 0; i < lim; i++)
        x[i] = y[i];
}

int main() {
//    file();
int ff = 0;
    while(~scanf("%d%d", &r, &c)) {
        ff++;
//    assert(ff <= 30);
        lim = 1 << r;
        for(int i = 0; i < r; i++)
            for(int j = 1; j <= c; j++)
                scanf(" %c", &G[i][j]);
        for(int i = 0; i < 2; i++)
            for(int j = 0; j < 2; j++)
                for(int k = 0; k < lim; k++) dp[i][j][k] = 0;
        LL ans = 0;
        dp[0][1][0] = 1;
        for(int i = 1; i <= c; i++) {
            int now = i & 1, pre = now ^ 1;
            for(int j = 0; j < lim; j++) dp[now][0][j] = dp[now][1][j] = 0;
            for(int j = 0; j < lim; j++)
                dp[now][0][j] = dp[pre][1][j], dp[pre][1][j] = add(dp[pre][1][j], dp[pre][0][j]);

            cpy(f, dp[pre][1]);
            FMT(i, 1);
            cpy(dp[now][1], h);
        }
        cout<<(dp[c&1][0][(1<<r)-1] + dp[c&1][1][(1<<r)-1])%mod<<'\n';
    }
    return 0;
}

Sacred Warrior

02-13

问题描述 :nnnSacred Warrior is a hero in DotA and his name is Huskar. The Sacred Warrior’s abilities revolve around shortening his own lifespan to spear his foes to burinng pieces.When we control the Sacred Warrior , we always want to give our enemies the most damage.So to simplify the problem,let’s consider the Sacred Warrior’s two skills as below:nn(1) Burning SpearnnnWhen the Sacred Warrior use the Burning Spear to attack his enemy, follow things will happen in order in the current second:nnn1.the enemy gets physical hurt by a normal attatk.nnn2.if the enemy’s burning degree BD is greater than zero,the enemy will gets BD*FI damage points.(at the beginning,the enemy’s burning degree is zero).nnn3.the enemy’s burning degree +1.nnn4.the remanent burning time become 6.nnn5.the Sacred Warrior’s HP decrease by D. The Sacred Warrior can not kill himself(don’t ask me why),that is,when the Sacred Warrior’s HP is less than or equal to D, the Sacred Warrior can not use Burning Spear!nnnWhen the Sacred Warrior use a single normal attack instead of Burning Spear, follow things will happen in order in the current second:nnn1.the enemy gets physical hurt by the normal attack.nnn2.if the enemy’s burning degree BD is greater than zero,the enemy will gets BD*FI damage points.(at the beginning,the enemy’s burning degree is zero).nnn3.the remanent burning time decrease by 1.nnn4.if the remanent burning time is zero, then the enemy’s burning degree become zero.nnn(2) Berserk’s bloodnnnThe Sacred Warrior’s base attack is A.nnnWhenever the Sacred Warrior’HP reduce R ,his attack will increase U, it means the Sacred Warrior will get ((HS-HC) / R)*U extra attack.(round down for division, hs is the original HP and the hc is the current HP).nnnThe normal attack NA is the sum of base attack and extra attack.nnnThe enemy has a defence degree DEFi and it change every second(the reason is complicated,such as Weave,Meld,Gush,Natural Order,Mekansm and so on).Whenever the enemy is attacked by a normal attack(a single normal attack or the first part of Burning Spear), if the enemy’s defence degree is greater than the normal attack, the enemy won’t get any physical hurt(but the burning effect is still effective), otherwise the enemy will get NA-DEFi damage.(NA is the current normal attack and the DEFi is the current defence degree).nnnEvery second The Sacred Warrior can choose using a single normal attack or Burning Spear to attack the enemy. But in order to make the most damage and lose too much HP is obviously not wise. So we use a evaluation function F=C – (HS-HE)*P to evaluate the fight. (hs is the original HP and the he is the HP after last second, C is the total damage he cause).Can you find the maximal F ? nn输入:nnnThe first line contains a single positive integer N( N <= 20 ), indicates the number of test cases.nnFor each test case:nnnThe first line contains eight integers T , HS , A , R , U , D , FI , P , T is the total time in seconds and the others is as described above.nnnThe second line contains T integers , the i-th integer is the defence degree DEFi in i-th second.nnn0< T < 200 , 0< HS < 100 , 0 < A < 5000 , 0< R < HS , 3<= D <= 10 , 0 <= U , FI , P <1000nnn0 <= DEFi <3000 nn输出:nnnThe first line contains a single positive integer N( N <= 20 ), indicates the number of test cases.nnFor each test case:nnnThe first line contains eight integers T , HS , A , R , U , D , FI , P , T is the total time in seconds and the others is as described above.nnnThe second line contains T integers , the i-th integer is the defence degree DEFi in i-th second.nnn0< T < 200 , 0< HS < 100 , 0 < A < 5000 , 0< R < HS , 3<= D <= 10 , 0 <= U , FI , P <1000nnn0 <= DEFi <3000nn样例输入:nn2 n5 10 5 3 2 3 2 1 n0 0 0 0 0 n5 10 1 7 1 3 5 1 n2 2 2 2 2n样例输出:nnCase #1: 52 nCase #2: 36

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭