日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

NOIP模拟题——B

發布時間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NOIP模拟题——B 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目描述】
我們要從n種食物選m個出來,安排一個順序吃掉它(們),每種食物有個美味值ai,然后我們有k個規則,每個規則有 xi, yi 和 ci三個數,如果吃完第xi種食物接下來馬上吃第yi種食物,第j種食物的美味值會增加ci。每種食物至多吃一個,求美味值最大的和是多少?
【輸入格式】
第一行有三個數n,m,k,k代表有k個規則(0<=k<=n*(n-1))。
第二行有n個數字代表每個食物的美味值。
接下去有k行,每行三個數xi,yi,ci。保證沒有任意兩個規則的xi和yi同時相同。
【輸出格式】
一行一個數代表答案
【sample input1】
2 2 1
1 1
2 1 1
【sample output1】
3
【sample input 2】
4 3 2
1 2 3 4
2 1 5
3 4 2
【sample output 2】
12
【數據范圍】
30% m<=n<=5 ,0<=ci,ai<=1e5
100% m<=n<=18,0<=ci,ai<=1e9

?

由于數據小,找的多,所以考慮狀壓DP。f[i][j]表示i狀態時最后一個數為j的最大值,若沒有吃完則每次找還未吃掉的和吃掉的(看做是當前狀態最后一個吃掉的),若吃多了就continue,否則(找完m個了)找dp[i][j]的最大值。

?

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 const long long maxn=20;
 7 long long dp[(1<<maxn)][maxn];
 8 long long v[maxn];
 9 long long pp[maxn][maxn];
10 long long n,m,k;
11 long long max(long long x,long long y)
12 {
13     if(x<y)return y;
14     return x;
15 }
16 long long _count(long long x)
17 {
18     long long an=0;
19     while(x)
20     {            
21         if(x&1)an++;
22         x>>=1;
23     }
24     return an;
25 }
26 int main()
27 {
28     freopen("b.in","r",stdin);
29     freopen("b.out","w",stdout);
30     scanf("%I64d%I64d%I64d",&n,&m,&k);
31     for(int i=0;i<=n-1;i++)
32     scanf("%I64d",&v[i]);
33     for(int i=1;i<=k;i++)
34     {
35         int x,y;long long z;
36         scanf("%d%d%I64d",&x,&y,&z);
37         pp[x-1][y-1]=z;
38     }
39     long long ans=0;
40     for(int i=0;i<=n-1;i++)
41     dp[(1<<i)][i]=v[i];
42     for(int i=0;i<(1<<n);i++)
43     {
44         int qw=_count(i);
45         if(qw>m)continue;
46         if(qw==m)
47         {
48             for(int j=0;j<=n-1;j++)
49             ans=max(ans,dp[i][j]);
50             continue;        
51         }
52         else
53         {
54             for(int j=0;j<=n-1;j++)//枚舉沒有吃的
55             {
56                 if(((1<<j)&i)==0)//沒有吃
57                 {
58                     for(int k=0;k<=n-1;k++)//枚舉最后吃的點
59                     if(((1<<k)&i))//吃過 
60                     dp[i|(1<<j)][j]=max(dp[i][k]+pp[k][j]+v[j],dp[i|(1<<j)][j]);
61                 } 
62             }
63             
64         }
65     }
66     printf("%I64d",ans);
67     return 0;
68 }

?

轉載于:https://www.cnblogs.com/937337156Zhang/p/6051322.html

總結

以上是生活随笔為你收集整理的NOIP模拟题——B的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。