UPC-遊戲智商+ 路標 (動態規劃+DFS)

都是細節處理,就直接放在一篇博客裏了c++

遊戲智商

時間限制: 1 Sec 內存限制: 128 MB
[提交] [狀態]
題目描述
熊的智商高仍是猴子的智商高,這或許是一個很難考究的問題。故事裏,吉吉國王一直標榜本身是最聰明最偉大的猴子國王,他的毛毛也是這麼堅信。而咱們的熊大和熊二卻一直相信他們熊熊纔是最聰明的。因而,在導遊光頭強的建議下,他們決定來一場 pk。
Pk 的內容是這樣的,有 n 個格子,每一個格子從左到右的編號依次是 1 到 n(編號也是位置),每一個格子上都有不一樣美味值的水果(猴子們和熊們都很喜歡吃水果,因此水果對他們來講頗有吸引力)。他們從位置 0 開始出發,手上有 AB 兩種卡片,A 卡有 na 張,B 卡片有nb 張。每次他們能夠用掉一張卡片,而後往前跳若干格,跳的格子數就是卡片上的數字。每跳到一個格子上,就能夠吃掉對應格子裏面的水果,得到水果的美味值。固然了,咱們會保證當卡片用完的時候,必定恰好跳到第 n 個格子上。卡片必定要用完,不能有剩餘。
遊戲的結果就是在相同的狀況下,誰能得到的水果美味值總和最大。熊熊們想要贏得這個比賽,因而熊二請求你的幫助。若是你能夠幫助他算出最大值,他甚至能夠把他最心愛的蜂蜜分享給你。
輸入
輸入第一行是3個整數n,na,nb,va,vb,n表示格子的總數,na表示A種卡片的數量,nb表示B種卡片的數量,va表示A種卡片上的數,vb表示B種卡片上的數。保證n必定等於nava+nbvb。
接下來n個整數,表示每一個格子上水果的美味值,注意美味值有多是負數。
輸出
輸出只有一行一個整數,表示卡片用完的時候,最多能夠獲得的美味值總和。
樣例輸入 Copy
3 1 1 2 1
1 2 3
樣例輸出 Copy
5
提示
共計有20個測試點。
對於第1-6個測試點,保證na=1,nb<=200,美味值都是小於等於10000的正整數。
對於第7-12個測試點,保證1<=na,nb<=12,美味值的絕對值小於等於10000。
對於100%的數據,保證1<=n<=20000,1<=na,nb<=2000,1<=va,vb<=5,va不等於vb,美味值的絕對值不超過1000000。
思路:
dp[i][j]表示用了i張A卡片和j張B卡片所獲取的美味值的最大值,狀態轉移方程:web

dp[i][j]=max(dp[i][j],dp[i-1][j]+a[i*va+j*vb]);
 dp[i][j]=max(dp[i][j],dp[i][j-1]+a[i*va+j*vb]);

注意一下細節處理
開始數組開小了一直TLE 就離譜數組

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define I_int ll
#define inf 0x3f3f3f3f
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
char F[200];
inline void out(I_int x) {
    if (x == 0) return (void) (putchar('0'));
    I_int tmp = x > 0 ? x : -x;
    if (x < 0) putchar('-');
    int cnt = 0;
    while (tmp > 0) {
        F[cnt++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while (cnt > 0) putchar(F[--cnt]);
    //cout<<" ";
}
const int maxn=2010;
ll dp[maxn][maxn];
///dp[i][j]表示用了i張A卡片和j張B卡片所獲取的美味值的最大值
ll n,na,nb,va,vb;
ll a[20010];
void AC(){
    n=read();na=read();nb=read();va=read();vb=read();
    for(ll i=1;i<=n;i++) a[i]=read();
    for(ll i=0;i<=na;i++){
        for(ll j=0;j<=nb;j++){
            if(i>=1) dp[i][j]=max(dp[i][j],dp[i-1][j]+a[i*va+j*vb]);
            if(j>=1) dp[i][j]=max(dp[i][j],dp[i][j-1]+a[i*va+j*vb]);
        }
    }
    out(dp[na][nb]);
}
int main(){
    AC();
    return 0;
}

路標

時間限制: 1 Sec 內存限制: 128 MB
[提交] [狀態]
題目描述
一天,小Z到OI總部旅遊,發現OI總部至關龐大,所以小Z經常迷路。本着「爲人民服務」的原則,小Z決定爲OI總部製做路標。OI總部由n個OI討論社組成,有些OI討論社間有路相連,路是無向的。小Z要在每一個OI討論社豎一個路標。小Z是一個喜歡標新立異的人,他製做的路標分兩種:黑路標和白路標。小Z規定:與白路標有路相連的必須是黑路標。因爲製做白路標比較省錢,因此他想知道最多有幾個OI討論社的路標爲白路標。(注意:OI總部不必定是連通圖。)
輸入
第一行包括2個整數m和n,表示路的條數和OI討論社的個數。
接下來的m行,每行兩個正整數x和y(x,y<=n且x≠y),表示第x個OI討論社與第y個OI討論社有路相連。
輸出
共一行,包括1個正整數ans,表示最多有幾個OI討論社的路標爲白路標。
樣例輸入 Copy
1 2
1 2
樣例輸出 Copy
1
提示
20%數據:n<=3
另有20%數據:m<=3
100%的數據知足:1<=n<=10
思路:
數據範圍很小,直接dfs就行,要注意看清題目中說的是白塊只能和黑塊相連,而黑塊則不受限制
讀錯題wa了5發svg

#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
int maxx=-1;
int g[maxn][maxn],col[maxn];
int n,m;
///1是白2是黑
bool check(int u){
    for(int i=1;i<=n;i++)
        if(g[u][i]||g[i][u]){
            if(col[i]==1&&col[u]==1) return 0;
        }
    return 1;
}
void dfs(int u){
    if(u==n+1){
        int tot=0;
        for(int i=1;i<=n;i++) if(col[i]==1) tot++;
        maxx=max(maxx,tot);
    }
    else{
        for(int i=1;i<=2;i++){
            col[u]=i;
            if(check(u)) dfs(u+1);
            col[u]=0;
        }
    }
}
void AC(){
    cin>>m>>n;
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>x>>y;
        g[x][y]=g[y][x]=1;
    }
    dfs(1);
    cout<<maxx<<endl;
}
int main(){
    AC();
    return 0;
}