洛谷1541 乌鬼棋 dp入门

题目链接:https://www.luogu.com.cn/problem/P1541

给定一个序列和一个操作序列,操作序列中只有1234四个数字,表示可以前进的步数,初始在1处,操作最后一定会全部用完,在此我们可以用dp描述四种状态:四种操作的使用次数,通过次数我们也可以得到目前的位置。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define dbg(args) cout<<#args<<":"<<args<<endl;
17 #define inf 0x3f3f3f3f
18 #define maxn 100005
19 int n,m,t,tmp;
20 int a[maxn];
21 int cnt[5],dp[41][41][41][41];
22 int main()
23 {
24     //freopen("input.txt","r",stdin);
25     //freopen("output.txt","w",stdout);
26     std::ios::sync_with_stdio(false);
27     scan(n);
28     scan(m);
29     f(i,1,n)scan(a[i]);
30     f(i,1,m)
31     {
32         scan(t);
33         cnt[t]++;
34     }
35     dp[0][0][0][0]=a[1];
36     f(i,0,cnt[1])//状态就是使用过的每张卡片的数量 
37         f(j,0,cnt[2])
38             f(k,0,cnt[3])
39                 f(l,0,cnt[4])
40                 {
41                     tmp=a[1+i+j*2+k*3+l*4];
42                     if(i)dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-1][j][k][l]+tmp);//指定用某张卡片
43                     if(j)dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-1][k][l]+tmp);
44                     if(k)dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k-1][l]+tmp);
45                     if(l)dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k][l-1]+tmp);
46                 }
47                 pf("%d",dp[cnt[1]][cnt[2]][cnt[3]][cnt[4]]);
48  } 

猜你喜欢

转载自www.cnblogs.com/randy-lo/p/12457397.html