列表

详情


NC230386. Archery

描述

301老周组织的一年一度 ACM 集训队运动会在这金秋10月如约而至。

为了增加趣味性,今年老周突发奇想,新增了一个射箭比赛项目。

区别于传统的积分规则,本次射箭项目也非常考验选手智力。

比赛规则如下:运动场上有n个箭靶,编号为1-n,射中编号为i 的箭靶可以得到

但如果累计射中编号为i的箭靶靶心 a_i 次,那么选手可以额外获得b_i的奖励分。

同时比赛也规定,箭靶 i最多被射中a_i次,超出 a_i不计分

集训队的小明报名参加了本项射箭比赛,虽然小明射箭技术精湛(百发百中),但在算法能力上确是一个小萌新。

现在他邀请聪明的你帮他计算一下,他最少需要射出几箭,才能保证他的得分不低 k

如果小明无论射出多少箭都无法获得大于等于k的得分,那么输出"wa"。
     

输入描述

1行输入正整数,表示运动场内箭靶的数量以及小明在射箭比赛中的最少得分。

行每行输入两个正整数,中间用空格隔开,含义如上文所述。

输出描述

输出答案。

示例1

输入:

2 70
3 50
5 80

输出:

3

说明:

小明可以选择在编号为 1 的箭靶上射箭 3 次,在得到基础分 30 分的前提下,他还可以得到奖励分 50 分,总分 80 分\geq k,这是最佳策略,答案等于 3。

示例2

输入:

2 40
3 50
5 80

输出:

2

说明:

小明可以选择在编号为2的箭靶上射箭 2 次,得分为2\times 20=40\geq k,此举为最佳策略,答案等于 2。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python3 解法, 执行用时: 277ms, 内存消耗: 4892K, 提交时间: 2022-06-21 09:33:24

n,k=map(int,input().split())
a=[0]
b=[0]
dp=[[0 for x in range(1001)] for y in range(11)] #n个靶子,x枝箭
suma=  0
for _ in range(n):
    x,y = map(int,input().split())
    a.append(x)
    b.append(y)
    suma=suma + x
for i in range(1,n+1):
    for j in range(1,suma+1):
        l = 0
        res = 0
        while l<= j and l<=a[i]:
            if l==a[i]:
                res = b[i]
            dp[i][j] =  max(dp[i][j],dp[i-1][j-l]+i*l*10+res)
            l = l +1

for i in range(1,suma+1):
    if dp[n][i] >=k:
        print(i)
        break
else:
    print('wa')
    
    



        
    

C++ 解法, 执行用时: 8ms, 内存消耗: 444K, 提交时间: 2022-04-04 22:15:55

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int q[100][1000];
int w[100];
long long f[1100];
int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		int a,b;
		cin>>a>>b;
		int t=1;
		while(t<=a){
			q[i][t]=t*i*10+(t==a)*b;
			t++;
		}
		w[i]=t;
	}
	for(int i=1;i<=n;i++){
		for(int j=1050;j>=0;j--){
			for(int k=1;k<=w[i];k++){
				if(j>=k){
					f[j]=max(f[j],f[j-k]+q[i][k]);
				}
			}
		}
	}
	int d=lower_bound(f,f+1020,k)-f;
	if(d==1020)cout<<"wa";
	else cout<<d;
}

上一题