Present [神奇 背包->最短路]

P r e s e n t Present Present


正 解 部 分 \color{red}{正解部分}

先设 p 1 p_1 p1 表示最小的 p p p .

p x p_x px 使用了 p 1 p_1 p1 次时, 可以用 p x p_x px p 1 p_1 p1 替代,
举个例子, 假如当前选物品的情况是 ∑ i = 2 N ( p 1 − 1 ) p i \sum\limits_{i=2}^N(p_1-1)p_i i=2N(p11)pi, 此时只要在 x ∈ [ 2 , N ] x∈[2, N] x[2,N] 中再选出任意一个物品 p x p_x px,
p 1 p_1 p1 p x p_x px 就可以被 p x p_x px p 1 p_1 p1 顶替 .

由此可以想到一个比暴力更优的背包 d p dp dp方法,
使用总容量 ∑ i = 1 N p 1 p i \sum\limits_{i=1}^Np_1p_i i=1Np1pi 的背包进行 d p dp dp, 然后对于每个 a i a_i ai 的判断, 只需将 a i a_i ai 模上 ∑ i = 1 N p 1 p i \sum\limits_{i=1}^Np_1p_i i=1Np1pi (等同于 ∑ i = 1 N p 1 p i \sum\limits_{i=1}^Np_1p_i i=1Np1pi全部被 p 1 p_1 p1 顶替了), 此时 a i a_i ai 一定是在背包容量内的, 直接判断即可 .

这样可以有 60 p t s 60pts 60pts .

使用 ∑ i = 1 N p 1 p i \sum\limits_{i=1}^Np_1p_i i=1Np1pi 为上界的原因是 ∑ i = 1 N ( p 1 − 1 ) p i \sum\limits_{i=1}^N(p_1-1)p_i i=1N(p11)pi p 1 p_1 p1 不能消任何数字的极限情况, 以 ∑ i = 1 N p 1 p i \sum\limits_{i=1}^Np_1p_i i=1Np1pi 为上界就可以顾及到所有的装填方法 .


思考能否以更小的背包容量解决这个问题,

x = y m o d    p 1 x=y \mod p_1 x=ymodp1, 且 x < y x < y x<y, 则 y − x = 0 m o d    p 1 y - x = 0 \mod p_1 yx=0modp1,
即对于 m o d   p 1 mod\ p_1 mod p1 相同的 x , y x, y x,y, 要凑成 y y y, 可以先凑成 x x x, 然后用 p 1 p_1 p1 x x x 的基础上填充 凑成 y y y,
换句话说, 若两个数模 p 1 p_1 p1 的值相同, 且除 p 1 p_1 p1 较小的那个数字可以凑出, 则较大的那个数字也可以凑出 .
上面这句话是 下方法的思想 核心 .

由此可以设 F [ x ] F[x] F[x] 表示 所有满足 i % p 1 = x i\%p_1 = x i%p1=x 且能被凑出的 i i i 中, 最小的 ⌊ i p 1 ⌋ \lfloor \frac{i}{p_1} \rfloor p1i,
用类似最短路的算法转移, 最后只需检查当前数字 a i a_i ai是否满足条件 F [ a i % p 1 ] ≤ ⌊ a i p 1 ⌋ F[a_i \% p_1] \le \lfloor \frac{a_i}{p_1} \rfloor F[ai%p1]p1ai 即可 .

时间复杂度 O ( p 1 l o g p 1 ) O(p_1logp_1) O(p1logp1) .


实 现 部 分 \color{red}{实现部分}

#include<bits/stdc++.h>
#define reg register
#define fi first
#define se second
typedef std::pair<int, int> pr;

int read(){
        char c;
        int s = 0, flag = 1;
        while((c=getchar()) && !isdigit(c))
                if(c == '-'){ flag = -1, c = getchar(); break ; }
        while(isdigit(c)) s = s*10 + c-'0', c = getchar();
        return s * flag;
}

int N;
int M;
int Ans;
int p[505];
int a[300005];
int F[200005];

int main(){
        freopen("present.in", "r", stdin);
        freopen("present.out", "w", stdout);
        N = read(), M = read();
        for(reg int i = 1; i <= N; i ++) p[i] = read();
        for(reg int i = 1; i <= M; i ++) a[i] = read();
        memset(F, 0x3f, sizeof F);
        F[0] = 0;
        std::priority_queue <pr, std::vector<pr>, std::greater<pr> > Q;
        Q.push(pr(0, 0));
        while(!Q.empty()){
                int ft = Q.top().se; Q.pop();
                for(reg int i = 2; i <= N; i ++){
                        int to = ft + p[i], cur = to%p[1];
                        if(F[cur] > F[ft] + to/p[1]){
                                F[cur] = F[ft] + to/p[1];
                                Q.push(pr(F[cur], cur));
                        }
                }
        }
        for(reg int i = 1; i <= M; i ++)
                if(F[a[i]%p[1]] <= a[i]/p[1]) Ans ++;
        printf("%d\n", Ans);
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
static int sbsa_uart_probe(struct platform_device *pdev) { struct uart_amba_port *uap; struct resource *r; int portnr, ret; int baudrate; /* * Check the mandatory baud rate parameter in the DT node early * so that we can easily exit with the error. */ if (pdev->dev.of_node) { struct device_node *np = pdev->dev.of_node; ret = of_property_read_u32(np, "current-speed", &baudrate); if (ret) return ret; } else { baudrate = 115200; } portnr = pl011_find_free_port(); if (portnr < 0) return portnr; uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), GFP_KERNEL); if (!uap) return -ENOMEM; ret = platform_get_irq(pdev, 0); if (ret < 0) { if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot obtain irq\n"); return ret; } uap->port.irq = ret; #ifdef CONFIG_ACPI_SPCR_TABLE if (qdf2400_e44_present) { dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n"); uap->vendor = &vendor_qdt_qdf2400_e44; } else #endif uap->vendor = &vendor_sbsa; uap->reg_offset = uap->vendor->reg_offset; uap->fifosize = 32; uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; snprintf(uap->type, sizeof(uap->type), "SBSA"); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ret = pl011_setup_port(&pdev->dev, uap, r, portnr); if (ret) return ret; platform_set_drvdata(pdev, uap); return pl011_register_port(uap); }linux内核uart驱动在设备注册时,使用acpi表定义的波特率来初始化串口,请根据我的要求和上述代码,在代码中添加这一功能
最新发布
06-07
好的,根据你的要求,我可以在该函数中添加获取ACPI表中定义的波特率的功能,并使用该波特率来初始化串口。代码如下: ``` static int sbsa_uart_probe(struct platform_device *pdev) { struct uart_amba_port *uap; struct resource *r; int portnr, ret; int baudrate; struct acpi_device *adev = ACPI_COMPANION(&pdev->dev); /* Check if ACPI companion device exists, and if so, read the current-speed property */ if (adev) { struct acpi_device_node *adev_node = acpi_node_get_device_node(adev->handle); if (adev_node) { struct fwnode_handle *fwnode = &adev_node->fwnode; ret = fwnode_property_read_u32(fwnode, "current-speed", &baudrate); if (ret) return ret; } } else if (pdev->dev.of_node) { /* If there is no ACPI companion device, fall back to reading the current-speed property from DT node */ struct device_node *np = pdev->dev.of_node; ret = of_property_read_u32(np, "current-speed", &baudrate); if (ret) return ret; } else { baudrate = 115200; } portnr = pl011_find_free_port(); if (portnr < 0) return portnr; uap = devm_kzalloc(&pdev->dev, sizeof(struct uart_amba_port), GFP_KERNEL); if (!uap) return -ENOMEM; ret = platform_get_irq(pdev, 0); if (ret < 0) { if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot obtain irq\n"); return ret; } uap->port.irq = ret; #ifdef CONFIG_ACPI_SPCR_TABLE if (qdf2400_e44_present) { dev_info(&pdev->dev, "working around QDF2400 SoC erratum 44\n"); uap->vendor = &vendor_qdt_qdf2400_e44; } else #endif uap->vendor = &vendor_sbsa; uap->reg_offset = uap->vendor->reg_offset; uap->fifosize = 32; uap->port.iotype = uap->vendor->access_32b ? UPIO_MEM32 : UPIO_MEM; uap->port.ops = &sbsa_uart_pops; uap->fixed_baud = baudrate; snprintf(uap->type, sizeof(uap->type), "SBSA"); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ret = pl011_setup_port(&pdev->dev, uap, r, portnr); if (ret) return ret; platform_set_drvdata(pdev, uap); return pl011_register_port(uap); } ``` 我添加的代码在函数开头处,首先判断是否存在ACPI companion device,如果存在则从其属性中读取波特率,否则从DT node中读取。读取到的波特率将被用于初始化串口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值