打了一場luogu的信心賽,驚訝地發現我不會t2,感覺像這樣在矩陣裡面的dp看起來很套路的樣子,但是仔細想想還是有很多需要注意的細節。
又想到之前貌似也考過一些類似的題目 然而我並沒有改 ,於是打算補補鍋。
目前大概想到幾道題,慢慢寫吧。
luogu p1006 傳紙條 && 小集訓模擬賽5 方格取數
很簡單的兩道題。注意到在「方格取數」中,因為每個方格的數字只能取一次,因此一定不會走重複路線(當然是在所有數字都大於0的情況下)。那就和「傳紙條」是同一道題了。
陣列可以開4維,3維,貌似還有二維?因為資料範圍太小就懶得寫優化了。(資料範圍大的話貌似就要用網路流了,本orzer不會)
**:
#include using namespace std;
typedef unsigned long long ll;
int a[25][25],vis[25][25],dp[25][25][25][25];
void solve()
for(int i=1;i<=n;++i)}}
}printf("%d",dp[n][n][n][n]);
}int main()
小集訓模擬賽12 t2 小象與老鼠
比上面的方格取數稍微難一點。因為每個點對答案造成的貢獻不僅僅是這個格仔的數,還有四連通的格仔。dp時候要考慮去重的問題。
具體是要記錄每乙個dp值是從它的上面或左面轉移過來。這樣分類討論就可以去重。
**:**:
#include using namespace std;
const int maxn=1000+10;
int a[maxn][maxn];
int val[maxn][maxn],dp[maxn][maxn][2];
int n,m;
void solve()
} for(int i=1;i<=n;++i)
} dp[1][1][0]=dp[1][1][1]=val[1][1]+a[1][1];
for(int i=1;i<=n;++i)
} }printf("%d",min(dp[n][m][1],dp[n][m][0]));
}int main()
luogu p6855 「ezec-4.5」走方格(2020.10.4 君のnoip のcsp信心賽 t2)
剛剛做的新題。剛開始的時候覺得很套路,幾分鐘就把**寫出來了。調了十分鐘後過不了樣例之後才發現自己錯了。
出題人的題解
看了題解才明白。。。我太菜了
首先顯然有\(o(n^4)\) 做法。列舉所有點,嘗試將其變成0即可。
然後顯然可以優化到o(n^3)因為發現如果變成0的點不再原來的最長路上,那麼對最終答案是沒有貢獻的。因此只需要列舉最長路上的點即可。
然後考慮優化。
對於最長路上的某個點,如果把它變成0。
第一種情況,如果把它變成0,它依然在最長路上。
第二種情況,其他的格仔會變成最長路上的點。
那應該怎麼計算呢?
可以發現,如果把乙個點變成0,不影響(1,1)到這個點之前的所有點的最長路。
同時還可以發現,如果反過來想,如果把乙個點變成0,也不影響這個點之後的所有點到(n,m)的最長路。
於是我們可以預處理出兩個陣列:
dp[i][j]表示(1,1)到(i,j)的最長路,f[i][j]表示(i,j)到(n,m)的最長路。
那麼把f[i][j]變成0的答案就是圖中黃色格仔向下走,紅色格仔向右走的答案取max。
最後把所有f[i][j]的答案取min即可。
**:
#include using namespace std;
typedef long long ll;
const int maxn=2000+10;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? eof : *p1++) : *p1++)
#define read() ( while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
char buf[1 << 20], *p1, *p2;
int a[maxn][maxn];
ll f[maxn][maxn],dp[maxn][maxn];
bool vis[maxn][maxn];
int n,m;
ll ans=0x3f3f3f3f3f3f3f3f;
struct node
node(int aa,int bb)
};queue q;
void solve()
} for(int i=1;i<=n;++i)
} for(int i=n;i;--i)
} q.push(node(n,m));
while(!q.empty())
for(int i=1;i<=n;++i)^a_i^2-(\sum_^a_i^2)^2\)
然後會發現,這個柿子的值只和每一項的值和每一項的平方有關。
於是可以定義轉移方程:
dp[i][j][k]表示當前走到(i,j),\(\sum_^a_s\) 的值為k,的最小的\(\sum_^a_s^2\)
然後轉移就很簡單啦!
**:#include using namespace std;
typedef long long ll;
const int maxn=100000+10;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? eof : *p1++) : *p1++)
#define read() ( while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc(); f * x; })
char buf[1 << 20], *p1, *p2;
ll dp[40][40][2000];
int a[40][40];
int n,m;
ll ans;
void solve()
} memset(dp,0x3f,sizeof(dp));
dp[1][1][a[1][1]]=a[1][1]*a[1][1];
for(int i=1;i<=n;++i)
}} for(int i=0;i<=1800;++i) if(dp[n][m][i]<=1e9) ans=min(ans,1ll*(n+m-1)*dp[n][m][i]-1ll*i*i);
printf("%lld\n",ans); }}
int main()
列舉裡面的介面的實現
列舉式乙個類,這個類,同樣也有類改由的功能,今天來說說列舉來實現介面。下面還是來看看 吧.首先我們定義乙個介面 介面裡面由兩個抽象方法.如下.public inte ce enuminte ce下滿我們來定義我們的列舉型別的類,分別由三個物件,分別有自己的構造方法.如下.public enum de...
Python裡面的字典
python 將這種資料型別叫做 dict 有的語言裡它的名稱是 hash 這兩種名字都會用到,不過這並不重要,重要的是它們和列表的區別。你看,針對列表你可以做這樣的事情 things a b c d print things 1 b things 1 z print things 1 z prin...
jquery裡面的 this 和this
當你用的是jquery時,就用 this 如果是js,就用this this html this html bam 這個裡的html 是jquery方法,用 this html 當然,js裡也有相似方法innerhtml,如果用innerhtml,就要這樣寫了,這裡的reset是js方法,所以同上得...